简体   繁体   English

(Monad m,Monoid o)=> mo的适用实例

[英]Applicative Instance for (Monad m, Monoid o) => m o?

Sorry for the terrible title. 对不起,标题不好。 I'm trying to make an instance of Applicative for a Monad wrapping a type that is a Monoid . 我试图做的一个实例, ApplicativeMonad包裹一个类型,是一种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

This doesn't work; 这行不通; GCHi complains with: 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)'

I realise that what I've written above may make no sense. 我意识到我上面写的可能没有任何意义。 Here is the context: I am trying to use the compos abstraction as described in the paper A pattern for almost compositional functions . 这里是上下文:我正在尝试使用论文A模式中所述的compos抽象来实现几乎复合的功能 Taking this tree (using the GADT version of compos ; I've simplified it a lot): 采取这棵树(使用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

I'm going to write a lot of functions which descend the tree and return a list of say errors or a set of strings whilst also requiring state as it goes down (such as the binding environment), such as: 我将编写许多函数,这些函数将树下移并返回一个错误列表或一组字符串,同时还需要在状态下降时提供状态信息(例如绑定环境),例如:

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)

I think these should all be able to be abstracted away by making composFoldM use compos for the (Monad m, Monoid o) => mo structure. 我认为应该通过使composFoldM(Monad m, Monoid o) => mo结构使用compos来抽象所有这些东西。 So to use it with the GADT Applicative version of compos found on page 575/576 of the paper . 因此,与GADT使用它Applicative版本compos的五百七十六分之五百七十五网页上找到的文件 I think I need to make an Applicative instance of this structure. 我认为我需要为此结构创建一个Applicative实例。 How would I do this? 我该怎么做? Or am I going down completely the wrong path? 还是我完全走错了路?

You want the Constant applicative from Data.Functor.Constant in the transformers package, which you can find here . 您希望Constant从应用性Data.Functor.Constanttransformers包,你可以找到这里

This Applicative has the following instance: Applicative具有以下情况:

instance (Monoid a) => Applicative (Constant a) where
    pure _ = Constant mempty
    Constant x <*> Constant y = Constant (x `mappend` y)

You can then compose Constant with any other applicative using Compose from Data.Functor.Compose (also in the transformers package), which you can find here . 然后,您可以使用Data.Functor.Compose Compose (也位于transformers程序包中) transformers Constant与其他任何应用程序进行Compose ,可以在此处找到。

Compose has this Applicative instance: 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)

You can then Compose your Constant applicative with any other Applicative (like State ) to keep both some state and a running Monoid tally. 然后,您可以Compose你的Constant应用性与其他任何Applicative (如State ),以保持双方的一些状态和运行Monoid相符。

More generally, you should read the paper The Essence of the Iterator Pattern , which discusses these patterns in more detail. 更一般而言,您应该阅读论文“迭代器模式的本质” ,其中更详细地讨论了这些模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM