数値をnewtypeした型の値として数値リテラルを使う

 Num型クラスに対してGeneralizedNewtypeDeriving拡張を使うことができるので、 例えばIntのnewtypeを作りたいけど、いちいち値コンストラクタを経るのが面倒だ という心配をする必要はない。

 貴方が想像している面倒さはこのようなものだ。

newtype Seconds = Seconds
  { unSeconds :: Int
  } deriving (Show, Eq)

incrementSeconds :: Seconds -> Seconds
incrementSeconds (Seconds x) = Seconds $ x + 1

main :: IO ()
main = do
  let seconds = Seconds 10
  print $ incrementSeconds seconds
  print . Seconds . abs . negate $ unSeconds seconds
-- {output}
-- Seconds {unSeconds = 11}
-- Seconds {unSeconds = 10}

 GeneralizedNewtypeDeriving拡張を使うことで、Seconds(+1)(-1), (*2)したり、 negateしてabsしたりすることができる。

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype Seconds = Seconds
  { unSeconds :: Int
  } deriving (Num, Show, Eq)

incrementSeconds :: Seconds -> Seconds
incrementSeconds = (+1)

main :: IO ()
main = do
  let seconds = 10
  print $ incrementSeconds seconds
  print . abs $ negate seconds
-- {output}
-- Seconds {unSeconds = 11}
-- Seconds {unSeconds = 10}

筆者プロフィール

my-latest-logo

aiya000(あいや)

せつラボ 〜圏論の基本〜」 「せつラボ2~雲と天使と関手圏~」 「矢澤にこ先輩といっしょに代数!」を書いています!

強い静的型付けとテストを用いて、バグを防ぐのが好き。Haskell・TypeScript。