【发布时间】:2020-03-07 16:29:25
【问题描述】:
我正在尝试理解do 表示法的规则。
这是一些类型检查的代码:
fff :: Maybe Int
fff = do
_ <- pure $ Just 100
(+10)
<$> Just 50
基本上是fff = (+10) <$> Just 50。我会假设上述内容可能会不进行类型检查 - 因为肯定每一行都应该在 Maybe 的上下文中,而 (+10) 不是。
为什么要进行上述类型检查?下面是一个更简单的例子:
fff :: Int -> Maybe Int
fff i = do
(+10)
<$> Just i
为什么上面的语法被认为是有效的?这不是“脱糖”吗:
fff i = ((+10) >>= (\i -> fmap (Just i))) i
这确实在 ghci 中给出了类型检查错误。
这是一个示例,它不按照与上述类似的缩进进行类型检查:
x :: Maybe Int
x = do
_ <- Just 1
undefined
<$> Just 5
(感谢上述示例中来自 FP 闲聊的@cvlad)
【问题讨论】:
-
您的问题不是关于 do 表示法,而是关于 GHC 解析器的内部工作原理。所以当你把它分成两行时它无法识别那个表达,那又怎样。不要在第二行缩进多于第一行的情况下这样做! :) 并且您没有包含错误消息。我希望这些错误会告诉你所涉及的子表达式,这样你就可以看到它是如何读取它们的。
-
@WillNess 这是个好问题。 为什么解析器/类型检查器接受一个而不接受另一个?
-
显然第一个符合some规则;如果您不知道,则无需将问题视为不值得提出而忽略。
-
@Chris 你已经彻底改变了这个问题。您将 do 块解释为绑定代码不正确:
<$>是 infix 二元运算符。
标签: haskell syntax do-notation