monadiccp-0.7.7: src/Control/Mixin/Mixin.hs
-- | Module with basic infrastructure for function inheritance
-- based on open rercusion.
--
-- See the work of William Cook.
--
-- We use the following terminology.
--
-- * A /closed/ function is an ordinary function.
--
-- * A /mixin/ function is an open function that can be
-- inherited from, or that extends another open function.
--
-- We obtain a closed function from a base mixin 'base'
-- and a number of mixin extensions 'e1',...,'en' as follows:
--
-- > mixin (en <@> ... <@> e1 <@> base)
--
module Control.Mixin.Mixin (
Mixin,
(<@>),
mixin,
mixinId,
mixinLift
) where
infixl 5 <@>
-- | Type of mixin functions.
type Mixin a = a -- the 'super' function
-> a -- the 'this' function
-> a -- the current function
-- | Mixin composition.
(<@>) :: Mixin a -> Mixin a -> Mixin a
(f1 <@> f2) super this = f1 (f2 super this) this
-- | Turn a mixin into a closed function.
mixin :: Mixin a -> a
mixin openF
= let closedF = openF errorF closedF
errorF = error $ "super called in base mixin"
in closedF
-- | Mixin identity function.
--
-- Identity for mixin composition:
--
--
-- > mixinId <@> f == f
-- > f <@> mixinId == f
--
mixinId :: Mixin a
mixinId super this = super
-- | Mixin lift function
--
-- > mixin . mixinLift = id
mixinLift :: (a -> b) -> Mixin (a -> b)
mixinLift f _ _ = f