use*_*996 3 monads haskell types return
我正在尝试理解Haskell中的Monads,在我无数次使用代码的实验中遇到过这样的事情:
f2 = do
return "da"
Run Code Online (Sandbox Code Playgroud)
并且它不想编译有关类型的巨大错误.我认为唯一重要的部分是:
No instance for (Monad m0) arising from a use of return'
The type variable `m0' is ambiguous
Run Code Online (Sandbox Code Playgroud)
那么我已将我的代码更改为:
f2 = do
return "da" :: IO [Char]
Run Code Online (Sandbox Code Playgroud)
而且效果非常好.但是当我试图弄乱一点并将类型更改为IO Int时再次出现错误.那么为什么这种类型实际上不是"含糊不清"?当我在返回之前添加一些内容时:
f2 = do
putStrLn "das"
return 2
Run Code Online (Sandbox Code Playgroud)
然后我不必指定返回的类型.那么有人可以解释我到底发生了什么吗?另外为什么在第一种情况下返回输出"da"?不是没有""?
首先让我们指出
do
return a
Run Code Online (Sandbox Code Playgroud)
完全一样
return a
Run Code Online (Sandbox Code Playgroud)
现在,问题是return有类型
return :: Monad m => a -> m a
Run Code Online (Sandbox Code Playgroud)
当你有一个像这样的声明
foo = bar
Run Code Online (Sandbox Code Playgroud)
哪里foo没有参数haskell使它"单态".这样做的结果是Haskell无法猜测是什么m,也不会概括它,所以你需要一个显式的类型签名.最普遍的是
f2 :: Monad m => m String
f2 = return "das"
Run Code Online (Sandbox Code Playgroud)
但你也可以使用IO或任何其他monad
f2 :: IO String
Run Code Online (Sandbox Code Playgroud)
最后,在你的最后一个例子中,既然你要返回2,你必须给出一个类型签名,表明你正在返回某种数字,比如
f2 :: IO Integer
Run Code Online (Sandbox Code Playgroud)
使用签名
f2 :: Monad m => m String
f2 = do
return "da"
Run Code Online (Sandbox Code Playgroud)
或使用语言扩展:
{-# LANGUAGE NoMonomorphismRestriction #-}
f2 = do
return "da"
Run Code Online (Sandbox Code Playgroud)
获得有效的代码