HaskellのMonadをあまり理解もしてないけど、使ってみました
Monadはまだよく分かりませんが、使ってみないことには分からないままなので、簡単なプログラムを走らせてみました。
ただ、コンパイルすると、ワーニングが出てしまいます。
warning: [-Wmissing-methods]
? No explicit implementation for
either ‘<*>’ or ‘GHC.Base.liftA2’
? In the instance declaration for ‘Applicative Clock’
|
6 | instance Applicative Clock where
プログラム
monad.hs
data Clock a = Hour a | Minute a | Second a | Over
instance Functor Clock where
fmap _ _ = Over
instance Applicative Clock where
pure _ = Over
instance Monad Clock where
Over >>= f = Over
Hour a >>= f = f a
Minute a >>= f = f a
Second a >>= f = f a
return a = Hour a
h :: Int -> Clock Int
h x = let i = x + 1
in
if i > 24
then Over
else Hour i
clockToString :: Clock Int -> (String , Int)
clockToString x =
case x of
Hour a -> ("Hour" , a)
Minute a -> ("Minute" , a)
Second a -> ("Second" , a)
Over -> ("Over" , 0)
main::IO()
main = do
let b = return 10 >>= h >>= h
let c = clockToString b
print c
実行結果
("Hour",12)
解説
data Clock a = Hour a | Minute a | Second a | Over
型Clock
は、時分秒と、あり得ない数(例えば85秒など)Over
をデータコンストラクタとして持っています。
instance Functor Clock where
fmap _ _ = Over
instance Applicative Clock where
pure _ = Over
instance Monad Clock where
Over >>= f = Over
Hour a >>= f = f a
Minute a >>= f = f a
Second a >>= f = f a
return a = Hour a
Clock
のインスタンスです。Monad
をインスタンスにする場合Functor
とApplicative
をインスタンスにしないといけないみたいです?
h :: Int -> Clock Int
h x = let i = x + 1
in
if i > 24
then Over
else Hour i
関数h
は、24を超えたらOver
を、そうでなければ、引数の数を+1してHour
に付けて返します。
let b = return 10 >>= h >>= h
>>=
演算子で、10に1づつ足して、clockToString
関数でClock
型を(String , Int)
にして、最後に結果を表示します。