为什么Prog A编译运行正常,而Prog B无法编译?谢谢
Prog A.
func :: String -> String
func a = a
mydofn a = do
x <- func a
return x
main = print "Finished"
Run Code Online (Sandbox Code Playgroud)
Prog B.
func :: Int -> Int
func a = a
mydofn a = do
x <- func a
return x
main = print "Finished"
Run Code Online (Sandbox Code Playgroud)
Prog B编译错误:
Couldn't match expected type `m0 t0' with actual type `Int'
In the return type of a call of `func'
In a stmt of a 'do' block: x <- func a
In the expression:
do { x <- func a;
return x }
Run Code Online (Sandbox Code Playgroud)
使用do-notation,此代码:
mydofn a = do
x <- func a
return x
Run Code Online (Sandbox Code Playgroud)
只是语法糖
mydofn a = func a >>= (\x -> return x)
Run Code Online (Sandbox Code Playgroud)
现在,>>=有型Monad m => m a -> (a -> m b) -> m b,但在第二个例子中,应用程序func a有一个类型Int,不能用统一Monad m => m a(因为Int是自己的,而不是内部的一些m),这是什么类型检查告诉你("无法匹配m a与Int").但为什么这在第一种情况下起作用?
Haskell中的字符串只是字符列表([Char]).在标准库中有一个Monad实例,[a]如下所示:
instance Monad [] where
m >>= k = foldr ((++) . k) [] m
return x = [x]
Run Code Online (Sandbox Code Playgroud)
所以[Char]与Monad m => m a(m = []和a = Char)统一,你的第一个例子就变成了
mydofn a = foldr ((++) . (\x -> [x])) [] (func a)
Run Code Online (Sandbox Code Playgroud)
或者等价的
mydofn a = concat . map (\x -> [x]) $ func a
Run Code Online (Sandbox Code Playgroud)
这只是将字符串的每个字符"abc"映射到单个字符串(映射到["a", "b", "c"]),然后将所有结果字符串连接在一起(["a", "b", "c"]变为"abc").