I am watching a Haskell online course, Reader monad chapter. The instructor gives the following example: this function takes a list and returns Nothing if it's empty or (Just head) otherwise.
safeHead = do
-- argument is implicit here
b <- null
if b then
return Nothing
else do
h <- head
return $ Just h
safeHead' = do
e <- id -- the error
if (null e)
then Nothing
else return $ Just (head e)
Run Code Online (Sandbox Code Playgroud)
第二个函数使用显式获取列表e <- id。但是,不幸的是,它对我不起作用。ghci给出了一个错误:
• Couldn't match expected type ‘Maybe [a]’
with actual type ‘a0 -> a0’
• Probable cause: ‘id’ is applied to too few arguments
In a stmt of a 'do' block: e <- id
In the expression:
do e <- id
if (null e) then Nothing else return $ Just (head e)
Run Code Online (Sandbox Code Playgroud)
该示例可能是3年前创建课程时由作者测试的(或者从一开始就是错误的)。
我怀疑是null采用了包装的值,而id没有:
Prelude> :t null
null :: Foldable t => t a -> Bool
Prelude> :t id
id :: a -> a
Run Code Online (Sandbox Code Playgroud)
怎么了,怎么解决?
实际上,您只是忘记了一个return。以下工作正常:
safeHead' = do
e <- id
if (null e)
then return Nothing -- need return here
else return $ Just (head e)
Run Code Online (Sandbox Code Playgroud)
或者您可以将其return排除在外:
safeHead' = do
e <- id
return $ if (null e)
then Nothing
else Just (head e)
Run Code Online (Sandbox Code Playgroud)