packages feed

edit-lenses-0.1: Data/Module/Class.hs

{-# LANGUAGE TypeFamilies, FlexibleContexts #-}
module Data.Module.Class where

import Data.Default
import Data.Maybe
import Data.Monoid

class (Default (V dX), Monoid dX) => Module dX where
	type V dX
	apply :: dX -> V dX -> Maybe (V dX)

applyDef :: Module dX => dX -> Maybe (V dX)
applyDef dx = apply dx def

applyTotal :: Module dX => dX -> V dX -> V dX
applyTotal dx x = fromJust (apply dx x)

applyDefTotal :: Module dX => dX -> V dX
applyDefTotal dx = applyTotal dx def

-- Morally, we have
-- foldMap :: Monoid b => (a -> State c b) -> ([a] -> State c b)
-- which does just what we want.  Unfortunately, this requires an
-- instance (Monad m, Monoid a) => Monoid (m a)
-- and an unhealthy amount of type munging to get in and out of State, curry
-- arguments, etc.  Since the instance above is most conveniently available
-- from the "reducers" package, which has a dependency redwood, and the
-- above-mentioned type-munging obfuscates the beautiful definition anyway, we
-- instead re-implement foldMap manually. It's not quite as beatiful
-- conceptually, but it makes for much easier reading.

foldState f ([]  , c) = (mempty, c)
foldState f (e:es, c) = (mappend e1 e2, c'') where
	(e2, c' ) = foldState f (es, c)
	(e1, c'') = f e c'