Ign*_*rov 5 monads haskell ghc do-notation applicative
考虑以下示例:
{-# 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'
Run Code Online (Sandbox Code Playgroud)
看起来不错!但不是:
[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.
Run Code Online (Sandbox Code Playgroud)
即使失败了:
instance Traversable (Tuple a) where
traverse f (Tuple x y) = do
y' <- f y
let unrelated = 1
return $ Tuple x y'
Run Code Online (Sandbox Code Playgroud)
因此,引入任何let
语句删除“应用性”与“应用性做”。为什么?
它将转化为
let unrelated = 1 in return $ Tuple x y'
Run Code Online (Sandbox Code Playgroud)
没有形式return <something>
,而应用性形式要求最后一个语句为a return
或pure
:
通常,do语句何时产生
Monad
约束的规则如下。如果do-expression具有以下形式:Run Code Online (Sandbox Code Playgroud)do p1 <- E1; ...; pn <- En; return E
如果在中没有
p1...pn
提及定义的变量E1...En
,并且p1...pn
都是变量或惰性模式,则该表达式仅需要Applicative
。否则,表达式将需要Monad
。该块可以返回纯表达E
取决于结果p1...pn
与任一return
或pure
。注意:最终声明必须与以下模式之一完全匹配:
Run Code Online (Sandbox Code Playgroud)return E return $ E pure E pure $ E
否则,GHC无法将其识别为return语句,并且
<$>
上面看到的使用转换不适用。特别是,轻微的变化,例如return . Just $ x
或let x = e in return x
不会被识别。
如果您在https://gitlab.haskell.org/ghc/ghc/wikis/applicative-do中查看关于废除糖的说明,那么它也不支持let
任何方式。
归档时间: |
|
查看次数: |
67 次 |
最近记录: |