Ger*_*wer 8 monads haskell type-mismatch do-notation
为什么允许使用此功能:
-- function 1
myfunc :: String
myfunc = do
x <- (return True)
show x
Run Code Online (Sandbox Code Playgroud)
这不是:
-- function 2
myfunc :: String
myfunc = do
x <- getLine
show x
Run Code Online (Sandbox Code Playgroud)
编译错误:
Couldn't match type `[]' with `IO'
Expected type: IO Char
Actual type: String
Run Code Online (Sandbox Code Playgroud)
我明白为什么功能 2 不应该工作,但为什么功能 1 工作呢?
为什么这会起作用:
-- function 3
myfunc = do
x <- getLine
return (show x)
Run Code Online (Sandbox Code Playgroud)
我知道它IO String然后返回,但是为什么函数 1 也没有被迫这样做?
sri*_*sri 12
在function1 中,do块 inmyfunc正在列表 monad 中工作,因为String实际上只是[Char]. 在那里,return True只需创建[True]. 当你这样做时x <- return True,“提取”True出来[True]并将其绑定到x. 下一行show x转换True为 String "True"。这是编译器值期望看到的返回值,最终工作正常。
同时,在function2 中,domyfunc 中的块也在列表 monad 上工作(出于同样的原因,String真的是[Char]),但调用getLine仅在IOmonad 中可用。所以不出所料,这失败了。
-- 编辑 1
OP增加了一个功能3
-- function 3
myfunc :: String
myfunc = do
x <- getLine
return (show x)
Run Code Online (Sandbox Code Playgroud)
不,这不应该出于同样的原因function2失败。
-- 编辑 2
OP 已更新 function3以修复复制粘贴错误。
-- function 3
myfunc = do
x <- getLine
return (show x)
Run Code Online (Sandbox Code Playgroud)
评论中提到了这一点,但为了清楚起见,这是有效的,因为当未指定类型信息时,GHC 会做出最佳推断,并且在看到 之后getLine,它会认为IO String它确实提供了getLine.
注意 - 我以尽可能随意的语气写了这个答案,而不会出错,目的是让它平易近人。
do块在任意Monad. 的Monad,在这种情况下,是[]。Monad列表的实例基于列表理解:
instance Monad [] where
return x = [x]
xs >>= f = [y | x <- xs, y <- f x]
Run Code Online (Sandbox Code Playgroud)
您可以do这样对符号进行脱糖:
myfunc :: String
myfunc = do
x <- (return True)
show x
-- ==>
myfunc = [y | x <- return True, y <- show x]
-- ==>
myfunc = [y | x <- [True], y <- show x]
Run Code Online (Sandbox Code Playgroud)
在列表理解中,x <- [True]实际上与 相同let x = True,因为您只从列表中绘制一个元素。所以
myfunc = [y | y <- show True]
Run Code Online (Sandbox Code Playgroud)
当然,“所有的清单y,以便y在show True”就是show True。
| 归档时间: |
|
| 查看次数: |
173 次 |
| 最近记录: |