标题已经说明了一切。实际上,我不明白为什么以下代码并没有打印出“Hello World”,而是与
在bind中,上下文或者说在IO术语中的“World”,第一个
那么,既然是这样,为什么当我们尝试将具有效果的IO映射到现有的IO Monad时编译器不会发出警告呢?
>>=
的输出不同。main = fmap putStrLn getLine
目前,这是我的推理思路,请检查是否有任何谬误。
如果我们将fmap
与>>=
进行比较
(>>=) :: Monad m => m a -> (a -> m b) -> m b
fmap :: Functor f => (a -> b) -> f a -> f b
在bind中,上下文或者说在IO术语中的“World”,第一个
m
和第二个m
除了类型以外完全不同。(a -> m b)
本质上重新创建了一个新的“World”。但是在Functor中,上下文f
是相同的,因此副作用是不可能的。那么,既然是这样,为什么当我们尝试将具有效果的IO映射到现有的IO Monad时编译器不会发出警告呢?
main :: IO ()
,你会注意到错误。在所有顶层定义中添加显式的类型签名是一个好的实践。 - user1804599