かとじゅんの技術日誌

技術の話をするところ

Maybeを自作してみる(Functor編)

モナドを理解するためにMaybeを自作することにしたので、適当にコードさらしてみる。モナド強者の方のツコッミあれば、よいコンテンツ化するのでは感。

data Option a = None | Some a
                deriving (Eq, Show)

instance Functor Option where
  fmap f (Some x) = Some (f x)
  fmap f None = None

getOrElse :: Option a -> a -> a
getOrElse None v = v
getOrElse (Some x) _ = x

get :: Option a -> a
get (Some x) = x

main = do
          let somes = map (Some) [1, 2, 3]
          let somes2 = map (fmap (+1)) somes
          let op1 = fmap (+1) $ Some 1
          let op2 = fmap (+1) None
          print somes2
          print $ getOrElse op1 0
          print $ get op1
          print $ getOrElse op2 0
          print $ get op2

とりあえず、Option独自データ型を用意してみた。 Optionが型コンストラクタ。None, Someは値コンストラクタ。derivingでEq, Showの型クラスのインスタンスを自動的に生成している。

んで、fmap, mapが使えるFunctorのインスタンスを定義。これでOptionに対してfmapが可能になる。ScalaのgetOrElse, getメソッド相当の関数を用意してみる。getOrElseでは第一引数にOption型、第二引数にデフォルト値を取り、戻り値として値を返す。値はOptionに指定されている型引数になる。getは書いてみたものの、Noneの場合は Non-exhaustive patterns in function get となるので、Haskellの流儀ではこういう関数は書いちゃいけない感。

次はApplicative Functorの実装を書いてみるか。