LoginSignup
2
1

More than 3 years have passed since last update.

HaskellのMonadを理解半ばで使う

Posted at

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をインスタンスにする場合FunctorApplicativeをインスタンスにしないといけないみたいです?

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)にして、最後に結果を表示します。

2
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1