打印时选择什么类型的多态表达式?

Mat*_*ick 5 haskell ghci

return "abc"在ghci中打印时的类型是什么?

问题的关键在于它在monad中是多态的:

ghci> :t return "abc"
return "abc" :: (Monad m) => m [Char]
Run Code Online (Sandbox Code Playgroud)

打印的内容取决于选择哪个monad:

ghci> return "abc" :: Maybe String
Just "abc"

ghci> return "abc" :: [] String
["abc"]
Run Code Online (Sandbox Code Playgroud)

但这是实际印刷的:

ghci> return "abc"
"abc"
Run Code Online (Sandbox Code Playgroud)

Ben*_*ood 7

当您expr在GHCi中键入表达式时,会发生以下情况:

  • 表达式是经过类型检查的.如果有错误,GHCi会告诉您错误并放弃.
  • 否则,说expr发现有类型t; GHC试图与之t对抗IO a.
  • 如果成功的话,就执行类似it <- expr,那么如果a是的实例Show,而不是(),它执行print it.
  • 如果失败了,而且t本身就是一个实例Show,GHCI确实有点像let it = expr,然后print it.
  • 否则,它会抱怨.

从本质上讲,您需要在GHCi提示符下运行IO操作并获取它们返回的值,以及使用纯值并查看所获得的值.这就是为什么GHCi的行为方式:如果看起来你正在使用IO动作,GHCi会这样做,然后如果该动作有一个可以显示并且有趣的结果(即没有())那么它会显示结果给你.如果它无法向您显示结果,那么这没什么大不了的,因为您可能只想运行IO操作; 如果你想要结果,你会用它命名<-.另一方面,如果您的表达似乎不是 IO动作,GHCi会计算它并向您显示,如果无法显示,那么GHCi无法做任何有用的事情(这次没有副作用) ,所以抱怨.

在这种情况下,return "abc"typechecks as IO String,并且String是一个实例Show,所以GHCi做了类似的事情

it <- return "abc"
print it
Run Code Online (Sandbox Code Playgroud)

根据monad法律,它与刚刚完成的相同

print "abc"
Run Code Online (Sandbox Code Playgroud)

结果.