gpt4 book ai didi

haskell - fmap putStrLn getLine 不执行 IO

转载 作者:行者123 更新时间:2023-12-03 13:32:02 28 4
gpt4 key购买 nike

实际上,标题说明了一切。我不明白为什么下面的代码实际上并没有打印“Hello World”而不是 >>=做。

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 术语中“世界”第一个 m第二个 m除了类型之外完全不同。 (a -> m b)本质上重建了一个新的“世界”。这在 Functor 中是不正确的,上下文 f是相同的,因此副作用是不可能的。

现在,如果确实如此,为什么当我们尝试 fmap 时编译器不给出警告?对现有 IO Monad 的有效 IO?

最佳答案

您快到了。 fmap putStrLn的类型是什么?

putStrLn      ::              String -> IO ()
fmap :: Functor f => (a -> b) -> f a -> f b
fmap putStrLn :: Functor f => f String -> f (IO ())

结果 fmap putStrLn getLine将是 IO (IO ()) ,即一个IO Action ,其中包含另一个IO Action 。不需要警告*,毕竟,这可能是您想要的。编译器无法确定您是否想要 m (m a)m a .

这实际上是 monad 的力量,它有一个操作可以让你加入这些操作:
join :: Monad m => m (m a) -> m a
-- join x = x >>= id

* 除了可能缺少的类型签名。你可以告诉 GHC 警告你那些带有 -fwarn-missing-signatures 的人。 .见 warnings and sanity-checking .

关于haskell - fmap putStrLn getLine 不执行 IO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25012233/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com