---------------------------------------------------------------------- -- | -- Module : Data.Fun -- Copyright : (c) Conal Elliott 2007 -- License : BSD3 -- -- Maintainer : conal@conal.net -- Stability : experimental -- -- Functions, with constant functions optimized. With instances of -- 'Functor', 'Applicative', 'Monad', and 'Arrow' ---------------------------------------------------------------------- module Data.Fun (Fun(..), apply) where import Control.Applicative (Applicative(..)) import Control.Arrow hiding (pure) -- | Constant-optimized functions data Fun t a = K a -- ^ constant function | Fun (t -> a) -- ^ non-constant function -- | 'Fun' as a function apply :: Fun t a -> (t -> a) apply (K a) = const a apply (Fun f) = f instance Functor (Fun t) where fmap f (K a) = K (f a) fmap f (Fun g) = Fun (f.g) -- Or use -- fmap f = (pure f <*>) instance Applicative (Fun t) where pure = K K f <*> K x = K (f x) cf <*> cx = Fun (apply cf <*> apply cx) instance Monad (Fun t) where return = pure K a >>= h = h a Fun f >>= h = Fun (f >>= apply . h) instance Arrow Fun where arr = Fun _ >>> K b = K b K a >>> Fun g = K (g a) Fun g >>> Fun f = Fun (g >>> f) first = Fun . first . apply second = Fun . second . apply K a' *** K b' = K (a',b') f *** g = first f >>> second g