这些幺半群实例已存在于某个地方吗?

Cub*_*bic 17 haskell

"某处"是"在标准库中或某些包中,这些包很小并且通用性足以使其成为相对无害的依赖".

import qualified Data.Map as M
import Data.Monoid
import Control.Applicative

newtype MMap k v = MMap {unMMap :: M.Map k v}
newtype MApplictive f a = MApplicative {unMApplicative :: f a}

-- M.unionWith f M.empty m = M.unionWith f m M.empty = m
-- f a (f b c) = f (f a b) c =>
--    M.unionWith f m1 (M.unionWith f m2 m3) =
--    M.unionWith f (M.unionWith f m1 m2) m3 
instance (Ord k, Monoid v) => Monoid (MMap k v) where
    mempty = MMap $ M.empty
    mappend m1 m2 = MMap $ M.unionWith mappend (unMMap m1) (unMMap m2)


instance (Applicative f, Monoid a) => Monoid (MApplicative f a) where
    mempty = MApplicative $ pure mempty
    mappend f1 f2 = MApplicative $ liftA2 mappend (unMApplicative f1) (unMApplicative f2)
Run Code Online (Sandbox Code Playgroud)

(这些实例应该满足幺半群定律 - 虽然没有为申请人证明这一点)

我问,因为我对这两者都有一些用处,我不喜欢重新定义已经存在的东西.

Boy*_*Jr. 1

像这样的东西吗?

class Functor f => Monoidal f where
    fempty :: Monoid m => f m
    fempty = fconcat []

    fappend :: Monoid m => f m -> f m -> f m
    fappend l r = fconcat [l, r]

    fconcat :: (Foldable c, Monoid m) => c (f m) -> f m
    fconcat = unMWrap $ foldMap MWrap

    {-# MINIMAL fempty, fappend | fconcat #-}

-- Could just be Pointed instead of Applicative, but that's not in base
applicativeFEmpty :: (Applicative f, Monoid m) => f m
applicativeFEmpty = pure mempty

applicativeFAppend :: (Applicative f, Monoid m) => f m -> f m -> f m
applicativeFAppend = liftA2 mappend

applicativeFConcat :: (Applicative f, Monoid m, Foldable c) => c (f m) -> f m
applicativeFConcat = fmap mconcat . sequenceA . foldMap (:[])

newtype MonoidWrap f a = MWrap { unMWrap :: f a }

instance Monoidal f, Monoid m => Monoid (MonoidWrap f m) where
    mempty = MWrap $ fempty . unMWrap
    mappend l r = MWrap $ fappend (unMWap l) (unMWrap r)
    mconcat = MWrap $ fconcat . map unMWrap
Run Code Online (Sandbox Code Playgroud)

另外,基础中所有合适数据类型的 Monoidal 实例?它不会涵盖 Data.Map.Map,这实际上是我对此模式最常见的用法,但可以简单地添加它。

不太确定 mconcat 和 fconcat 之间的递归。可能是个问题。