Monadの練習
Int型の数値の確認
Prelude> 1 1 Prelude> :t 1 1 :: Num a => a
Int型の配列の型の確認
Prelude> :t [1] [1] :: Num t => [t]
Maybe Int型の型の確認
Prelude> :t Just 1 Just 1 :: Num a => Maybe a
returnしたときの型の確認 このでは何のMonadであるかはわからない。Int型のデータを持つなんらかのMonad
Prelude> :t return 1 return 1 :: (Monad m, Num a) => m a
returnしたときに型を明示的に指定する。 Numは型クラスなので、Numの配列(?)はエラーとなる。 Int型の配列がreturnできる。
Prelude> :t return 1 :: [Num] <interactive>:1:14: Expecting one more argument to `Num' In an expression type signature: [Num] In the expression: return 1 :: [Num] Prelude> :t return 1 :: [Int] return 1 :: [Int] :: [Int]
returnにてMaybe Int型を明示的に指定する。
Prelude> :t return 1 :: Maybe Int return 1 :: Maybe Int :: Maybe Int
配列モナドのバインドの練習
Prelude> (return 1 :: [Int]) >>= (\x -> [x*2]) [2] Prelude> (return 1 :: [Int]) >>= (\x -> [x*4]) [4] Prelude> (return 1 :: [Int]) >>= (\x -> [x*4]) >>= (\x -> [x + 3]) [7] Prelude> (return 1) >>= (\x -> [x*4]) >>= (\x -> [x + 3]) [7]
Maybeモナドのバインドの練習
Prelude> (return 1) >>= (\x -> Just(4*1)) Just 4 Prelude> (return 1) >>= (\x -> Just(4*1)) >>= (\x -> Just(x+3)) Just 7
異なるモナドはバインドできない。
Prelude> (return 1) >>= (\x -> Just(4*1)) >>= (\x -> [x + 3]) <interactive>:29:45: Couldn't match type `[]' with `Maybe' Expected type: Maybe b0 Actual type: [b0] In the expression: [x + 3] In the second argument of `(>>=)', namely `(\ x -> [x + 3])' In the expression: (return 1) >>= (\ x -> Just (4 * 1)) >>= (\ x -> [x + 3])
printの型の確認
Prelude> :t print "a" print "a" :: IO ()
returnにIOモナドを明示的に指定するとエラーとなる。 returnでChar型をもつ何らかのモナドを指定しているが、型の指定は何もない(!)モナドだから。
Prelude> :t return 'a' :: IO () <interactive>:1:8: Couldn't match expected type `()' with actual type `Char' In the first argument of `return', namely 'a' In the expression: return 'a' :: IO ()
returnで何も返さなければ、型指定にIO ()はOK
Prelude> :t return ():: IO () return ():: IO () :: IO ()
Char型をもつIOモナドであれば、OK
Prelude> :t return 'a' :: IO Char return 'a' :: IO Char :: IO Char
IOモナドの順次実行
Prelude> print "a" >> print "b" "a" "b"
IOモナドのバインド。 引数を明示的に無視する必要がある。
Prelude> print "a" >> print "b" >>= print "c" <interactive>:52:28: Couldn't match expected type `() -> IO b0' with actual type `IO ()' In the return type of a call of `print' Probable cause: `print' is applied to too many arguments In the second argument of `(>>=)', namely `print "c"' In the expression: print "a" >> print "b" >>= print "c" Prelude> :t print print :: Show a => a -> IO () Prelude> print "a" >> print "b" >>= \x -> print "c" "a" "b" "c"
Prelude>