这是我的代码:
doSomething :: IO Bool -> IO () -> IO ()
doSomething cond body = cond >>= ( \condition -> if condition then return else body )
它给了我这个错误:
Couldn't match expected type `IO ()' with actual type `a0 -> m0 a0'
In the expression: return
In the expression: if condition then return else body
In the second argument of `(>>=)', namely
`(\ condition -> if condition then return else body)'
我也尝试了这种等效符号:
whileM :: IO Bool -> IO () -> IO ()
whileM cond body = do
condition <- cond
if condition then return else body
但我或多或少都有相同的符号。我理解错误是该函数希望我返回一个Monad,而是返回一个将a0
转换为monad m a0
的函数。我该如何解决这个问题?
答案 0 :(得分:7)
与(几乎所有)其他语言不同,在Haskell中,return
并不意味着“终止此代码并返回到调用它的下一行”。
在Haskell中,它(粗略地)意味着“将这个东西包裹在monad中”。在do
表示法的上下文中,这通常发生在代码中将控制权交还给“调用者”的地方(同样,这不是真正正确的单词,但在这个类比中会这样做)
因此,return
需要一个参数(要包装的内容).... return
属于Monad m => a -> m a
类型,但您的函数返回类型{{1} }。因此,你需要包装的是IO ()
类型,只有一个元素的类型,'()'本身。
将()
更改为return
,看看是否有效。