[英]Applicative Instance for (Monad m, Monoid o) => m o?
对不起,标题不好。 我试图做的一个实例, Applicative
的Monad
包裹一个类型,是一种Monoid
。
instance (Monad m, Monoid o) => Applicative (m o) where
pure x = return mempty
xm <*> ym = do
x <- xm
y <- ym
return $ x `mappend` y
这行不通; GCHi抱怨:
Kind mis-match
The first argument of `Applicative' should have kind `* -> *',
but `m o' has kind `*'
In the instance declaration for `Applicative (m o)'
我意识到我上面写的可能没有任何意义。 这里是上下文:我正在尝试使用论文A模式中所述的compos
抽象来实现几乎复合的功能 。 采取这棵树(使用GADT版本的compos
;我已经对其进行了很多简化):
data Tree :: * -> * where
Var :: String -> Expr
Abs :: [String] -> Expr -> Expr
App :: Expr -> [Expr] -> Expr
class Compos t where
compos :: Applicative f => (forall a. t a -> f (t a)) -> t c -> f (t c)
instance Compos Tree where
compos f t =
case t of
Abs ps e -> pure Abs <*> pure ps <*> f e
App e es -> pure App <*> f e <*> traverse f es
_ -> pure t
我将编写许多函数,这些函数将树下移并返回一个错误列表或一组字符串,同时还需要在状态下降时提供状态信息(例如绑定环境),例如:
composFoldM :: (Compos t, Monad m, Monoid o) => (forall a. t a -> m o) -> t c -> m o
composFoldM f = ???
checkNames :: (Tree a) -> State (Set Name) [Error]
checkNames e =
case e of
Var n -> do
env <- get
-- check that n is in the current environment
return $ if Set.member n env then [] else [NameError n]
Abs ps e' -> do
env <- get
-- add the abstractions to the current environment
put $ insertManySet ps env
checkNames e'
_ -> composFoldM checkNames e
data Error = NameError Name
insertManySet xs s = Set.union s (Set.fromList xs)
我认为应该通过使composFoldM
对(Monad m, Monoid o) => mo
结构使用compos
来抽象所有这些东西。 因此,与GADT使用它Applicative
版本compos
的五百七十六分之五百七十五网页上找到的文件 。 我认为我需要为此结构创建一个Applicative
实例。 我该怎么做? 还是我完全走错了路?
您希望Constant
从应用性Data.Functor.Constant
在transformers
包,你可以找到这里 。
本Applicative
具有以下情况:
instance (Monoid a) => Applicative (Constant a) where
pure _ = Constant mempty
Constant x <*> Constant y = Constant (x `mappend` y)
然后,您可以使用Data.Functor.Compose
Compose
(也位于transformers
程序包中) transformers
Constant
与其他任何应用程序进行Compose
,可以在此处找到。
Compose
具有此Applicative
实例:
instance (Applicative f, Applicative g) => Applicative (Compose f g) where
pure x = Compose (pure (pure x))
Compose f <*> Compose x = Compose ((<*>) <$> f <*> x)
然后,您可以Compose
你的Constant
应用性与其他任何Applicative
(如State
),以保持双方的一些状态和运行Monoid
相符。
更一般而言,您应该阅读论文“迭代器模式的本质” ,其中更详细地讨论了这些模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.