haskell - subgrupos - ¿Estas instancias de monoides ya existen en algún lugar?
monoide pdf (3)
¿Algo como esto?
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
Además, ¿instancias monoidales para todos los tipos de datos adecuados en la base? No abarcaría Data.Map.Map, que en realidad es mi uso más común de este patrón, pero podría agregarse de manera simple.
No estoy seguro de la recursión entre mconcat y fconcat. Podría ser un problema.
"En algún lugar" está "en la biblioteca estándar o en algún paquete que sea lo suficientemente pequeño y general como para que sea una dependencia relativamente inofensiva".
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)
(Estas instancias deberían satisfacer las leyes de los monoides, aunque no se molestaron en demostrarlo para el aplicativo)
Lo pregunto porque tengo algo de uso para ambos y no me gusta redefinir las cosas que ya están allí.
Creo que la respuesta a esta pregunta es "No", por lo que ha permanecido sin una respuesta positiva durante tanto tiempo.
Estas instancias existen en reducers , un paquete de Edward Kmett. Su MApplicative
se conoce allí como Ap
, mientras que MMap
se codifica a través del nuevo tipo de Union
.