fmap putStrLn getLine不执行IO [英] fmap putStrLn getLine does not perform IO

查看:40
本文介绍了fmap putStrLn getLine不执行IO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

实际上,标题说明了一切.我不明白为什么下面的代码与>> = 的行为相反,实际上并未打印"Hello World".

The title said it all, actually. I can't understand why this following code does not actually print "Hello World" as opposed of what >>= does.

main = fmap putStrLn getLine

目前,这是我的推理路线,请检查其是否有谬误.

Currently, here is my line of reasoning, please check if it has any fallacy.

如果我们将 fmap >> =

(>>=) :: Monad m => m a -> (a -> m b) -> m b
fmap :: Functor f => (a -> b) -> f a -> f b

在绑定中,上下文或以IO术语世界"而言,第一个 m 和第二个 m 在类型上完全不同.(a-> m b)本质上重新创建了一个新的世界".在Functor中并非如此,上下文 f 是相同的,因此没有副作用.

In bind, the context, or in IO terms "World" the first m and the second m is entirely different aside of the types. (a -> m b) essentially recreates a new "World". This is not true in Functor, the context f are the same hence side effects are impossible.

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

Now, if that's indeed the case, why doesn't the compiler gives a warning when we try to fmap an effectful IO to an existing IO Monad?

推荐答案

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

You're almost there. What is the type of 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动作,其中包含另一个IO动作.不需要警告 * ,毕竟,这可能就是您想要的.编译器无法确定您想要的是 m(m a)还是 m a .

And as a result fmap putStrLn getLine will be IO (IO ()), that is, an IO action, which contains another IO action. There's no need for a warning*, after all, this could be what you intended. The compiler cannot determine whether you wanted m (m a) or m a.

这实际上是单子的力量,它具有使您能够加入这些动作的操作:

That's actually the power of a monad, it has an operation which enables you to join those actions:

join :: Monad m => m (m a) -> m a
-- join x = x >>= id


*,但可能缺少类型签名.您可以告诉GHC对具有 -fwarn-missing-signatures 的用户发出警告.请参阅警告和健全性检查.


* except maybe for the missing type signature. You can tell GHC to warn you about those with -fwarn-missing-signatures. See warnings and sanity-checking.

这篇关于fmap putStrLn getLine不执行IO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆