【问题标题】:Fieldwise distribution of Monoid, Applicative, Monad etc for Haskell records用于 Haskell 记录的 Monoid、Applicative、Monad 等的字段分布
【发布时间】:2014-07-15 13:30:32
【问题描述】:

是否有一个包大致执行以下操作:

给定一个记录:

data R = R { a :: TypeA,
             b :: TypeB,
             c :: TypeC }

导出一个提升的记录:

data R_L f = R_L { a_L :: f TypeA,
                   b_L :: f TypeB,
                   c_L :: f TypeC }

并提供几个类似的实例和功能:

instance (Monoid (f TypeA), Monoid (f TypeB), Monoid (f TypeC))
         => (Monoid (R_L f)) where
  mempty = R_L mempty mempty mempty
  mplus a b = ...fieldwise mplus...

sequenceR :: (Monad m) => R_L m -> m R
sequenceR = ... run fields, sum results ...
sequenceRA :: (Applicative m) => R_L m -> m R
sequenceRA x = R <$> a_L x <*> b_L x <*> c_L x

可能还有其他人。是否有提供此功能的包?如果没有,最好使用哪种机制(TH?泛型?)来实现它?

【问题讨论】:

  • 那个幺半群实例没有意义,因为f 有一种* -&gt; *。可以与MonadPlus 合作,您是这个意思吗?
  • 经过编辑使 Monoid 实例更加清晰,但我也欢迎 MonadPlus 实例。

标签: haskell template-haskell


【解决方案1】:

幺半群部分可以使用generic-deriving,它提供了一个替代GMonoid,其中泛型自动成为一个实例。

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances, FlexibleContexts, DefaultSignatures #-}

import Data.Monoid
import qualified Generics.Deriving.Monoid as M

data R_L f = R_L { a :: f [()],
                   b :: f String,
                   c :: f () } deriving (Generic)

现在您可以执行以下操作:

*Main> let x = R_L (Just [()]) Nothing (Just ()) `M.gmappenddefault` R_L (Just [()]) (Just "foo") (Just ())
*Main> a x
Just [(),()]
*Main> b x
Just "foo"
*Main> c x
Just ()

(我仍在研究通用的Show 实例。)

一个普通的Monoid 实例可以如下创建(想想,这可能又被称为样板......):

instance (Monoid (f [()]), Monoid (f String), Monoid (f ())) => Monoid (R_L f) where
    mempty = M.memptydefault
    mappend = M.mappenddefault

在包中,还有other 派生实例FunctorTraversableFoldable

MonadApplicative 可以使用类似于现有实例的泛型建模,如果您更改类型的类型;虽然,可能不是您喜欢的方式,因为我认为,它们仅作为字段类型的 product 函子才有意义,而不是您建议的那样。

【讨论】:

  • 感谢泛型派生提示,这应该很有用。请注意,尽管您的建议不是从 R 派生出 R_L,所以它对我来说是部分解决方案。
  • 哦,对不起,我误解/过度解读了您对 deriving 的使用。我仍然会留下答案,因为你发现它很有帮助。
【解决方案2】:

本着真正的开源精神,我编写了自己的库:

http://hackage.haskell.org/package/fieldwise

https://github.com/gracjan/fieldwise

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-14
    • 2016-10-10
    • 2012-11-12
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    相关资源
    最近更新 更多