在HaskellWiki的Do notation considered harmful中,Useful applications一节中,我发现:
It shall be mentioned that the do sometimes takes the burden from you to write boring things.
E.g. in
getRight :: Either a b -> Maybe b getRight y = do Right x <- y return x
a
case
on y is included, which calls fail if y is not a Right (i.e. Left), and thus returns Nothing in this case.
我想尝试在模式不匹配时调用 fail
(Nothing
),这听起来很有趣。然而,语法看起来是错误的——我们不在Either
单子中,那么我们怎么能从y
中提取任何东西呢?
实际上,我尝试了一下,结果出现了 "Couldn't match type `Either a' with `Maybe'"。所以让我们在这里使用正确的模式匹配器,也就是let
:
getRight y = do { let (Right x) = y; return x }
这给了我一个语法错误 "解析错误,输入为`}'"。虽然我不理解为什么它不能工作,但让我们用多行注释来写出它:
getRight y = do
let (Right x) = y
return x
啊,看起来至少解析是有效的。但是:
*Main> getRight (Right 5)
Just 5
*Main> getRight (Left 5)
Just *** Exception: […]\test.hs:16:13-25: Irrefutable pattern failed for pattern (Data.Either.Right x)
-- `Nothing` was expected
发生了什么?所以我的问题是:
- 这里发生了什么?为什么我的分号大括号行不起作用?
- 如何正确做(使用
do
,其他都很简单)?
getRight
的解析错误是因为一般来说,一旦你切换到显式的大括号和分号,那么所有嵌套在内部的语言结构也必须使用显式的大括号和分号:getRight y = do { let { Right x = y }; return x }
。 - kosmikuslet getRight x =
…中加上“let”。 - Bergi