[英]Why does a “let” statement force an “applicative do” block into requiring a monad constraint?
考虑这个例子:
{-# language ApplicativeDo #-}
module X where
data Tuple a b = Tuple a b deriving Show
instance Functor (Tuple a) where
fmap f (Tuple x y) = Tuple x (f y)
instance Foldable (Tuple a) where
foldr f z (Tuple _ y) = f y z
instance Traversable (Tuple a) where
traverse f (Tuple x y) = do
y' <- f y
let t' = Tuple x y'
return $ t'
看起来不错:但没有:
[1 of 1] Compiling X ( X.hs, interpreted )
X.hs:15:9: error:
• Could not deduce (Monad f) arising from a do statement
from the context: Applicative f
bound by the type signature for:
traverse :: forall (f :: * -> *) a1 b.
Applicative f =>
(a1 -> f b) -> Tuple a a1 -> f (Tuple a b)
at X.hs:14:5-12
Possible fix:
add (Monad f) to the context of
the type signature for:
traverse :: forall (f :: * -> *) a1 b.
Applicative f =>
(a1 -> f b) -> Tuple a a1 -> f (Tuple a b)
• In a stmt of a 'do' block: y' <- f y
In the expression:
do y' <- f y
let t' = Tuple x y'
return $ t'
In an equation for ‘traverse’:
traverse f (Tuple x y)
= do y' <- f y
let t' = ...
return $ t'
|
15 | y' <- f y
| ^^^^^^^^^
Failed, no modules loaded.
即使这失败了:
instance Traversable (Tuple a) where
traverse f (Tuple x y) = do
y' <- f y
let unrelated = 1
return $ Tuple x y'
因此,引入任何let
语句都会从"applicative do"中删除"applicative " 。 为什么?
它会转化为
let unrelated = 1 in return $ Tuple x y'
它没有形式return <something>
,而 applicative do 要求最后一个语句是return
或pure
:
一般而言,do 语句何时引发
Monad
约束的规则如下。 如果 do 表达式具有以下形式:do p1 <- E1; ...; pn <- En; return E
其中没有任何由
p1...pn
定义的变量在E1...En
中被提及,并且p1...pn
都是变量或惰性模式,那么表达式将只需要Applicative
。 否则,表达式将需要Monad
。 该块可能会返回一个纯表达式E
取决于结果p1...pn
与return
或pure
。注意:最后的语句必须完全匹配以下模式之一:
return E return $ E pure E pure $ E
否则 GHC 无法将其识别为 return 语句,并且我们上面看到的使用
<$>
的转换不适用。 特别是return. Just $ x
return. Just $ x
或let x = e in return x
不会被识别。
如果您查看https://gitlab.haskell.org/ghc/ghc/wikis/applicative-do中的脱糖描述,它也不支持let
以任何方式。
你希望这个去糖的应用表达是什么? monadic 表达式是一系列链式作用域,因此let
引入一个扩展到所有剩余作用域的绑定是有意义的,但是通过应用程序,各种表达式不能真正相互依赖,所以它没有 scope对let
into 进行脱糖是有意义的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.