作者:勉情于你 | 来源:互联网 | 2022-12-05 18:43
我理解(有些)monad并理解运算符<- 将从monad中提取值.
但它如何适用于不同类型?
通常,我已经看到它被用于从IO monad中提取字符串.但是在下面的示例代码中,我无法看到它为什么在主要的第3行失败,抱怨它期待一种类型的IO int?编译器如何推断需要IO int?
它(<-
)在multWithLog
方法中做了什么?
import Control.Monad.Trans.Writer.Lazy
main = do
putStrLn $ show $ logNumber 3 -- prints WriterT (Identity (3,["Got Number: 3"]))
putStrLn $ show $ multWithLog -- prints WriterT (Identity (3,["Got Number: 3"]))
_ <- logNumber 3 -- fails with Couldn't match type ‘WriterT [String] Data.Functor.Identity.Identity’ with ‘IO’
-- Expected type: IO Int
-- Actual type: Writer [String] Int
putStrLn "test"
logNumber :: Int -> Writer [String] Int
logNumber x = writer (x, ["Got Number: " ++ show x])
multWithLog :: Writer [String] Int
multWithLog = do
a <- logNumber 3
--b <- logNumber 5
return a
melpomene..
6
do
块中的每个语句必须来自相同的monadic类型.
在
multWithLog = do
a <- logNumber 3
return a
我们已经logNumber 3 :: Writer [String] Int
和return a :: (Monad m) => m Int
(这是多态),所以整个事情typechecks为Writer [String] Int
(带m = Writer [String]
,这是一个单子).
在
main = do
putStrLn $ show $ logNumber 3
putStrLn $ show $ multWithLog
_ <- logNumber 3
putStrLn "test"
我们有putStrLn ... :: IO ()
和logNumber 3 :: Writer [String] Int
.这是一个类型错误,因为Writer [String]
它不一样IO
.
根本原因是do
块只是调用>>=
和的句法糖>>
.你main
真的意味着
main =
(putStrLn $ show $ logNumber 3) >>
(putStrLn $ show $ multWithLog) >>
logNumber 3 >>= \_ ->
putStrLn "test"
同
(>>) :: (Monad m) => m a -> m b -> m b
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
这要求类型m
始终保持不变.
1> melpomene..:
do
块中的每个语句必须来自相同的monadic类型.
在
multWithLog = do
a <- logNumber 3
return a
我们已经logNumber 3 :: Writer [String] Int
和return a :: (Monad m) => m Int
(这是多态),所以整个事情typechecks为Writer [String] Int
(带m = Writer [String]
,这是一个单子).
在
main = do
putStrLn $ show $ logNumber 3
putStrLn $ show $ multWithLog
_ <- logNumber 3
putStrLn "test"
我们有putStrLn ... :: IO ()
和logNumber 3 :: Writer [String] Int
.这是一个类型错误,因为Writer [String]
它不一样IO
.
根本原因是do
块只是调用>>=
和的句法糖>>
.你main
真的意味着
main =
(putStrLn $ show $ logNumber 3) >>
(putStrLn $ show $ multWithLog) >>
logNumber 3 >>= \_ ->
putStrLn "test"
同
(>>) :: (Monad m) => m a -> m b -> m b
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
这要求类型m
始终保持不变.