{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-} ---------------------------------------------------------------------- -- | -- Module : Data.FunArr -- Copyright : (c) Conal Elliott 2007 -- License : LGPL -- -- Maintainer : conal@conal.net -- Stability : experimental -- Portability : portable -- -- Conversion between arrow values and wrapped functions. ---------------------------------------------------------------------- module Data.FunArr ( FunArr(..), wapl ) where import Control.Monad.Identity import Data.Tupler infixr 0 $$ -- FunArr application -- | Convert between an arrow value and a \"wrapped function\". The \"arrow\" -- doesn't really have to be an arrow. I'd appreciate ideas for names & -- uses. class FunArr (~>) w | (~>)->w, w->(~>) where -- | Convert a @w@-wrapped function to an arrow value toArr :: w (a->b) -> (a ~> b) -- | Apply an arrow to a @w@-wrapped value ($$) :: (a ~> b) -> w a -> w b -- | Apply a wrapped function to a wrapped value wapl :: FunArr (~>) w => w (a->b) -> w a -> w b wapl f a = toArr f $$ a -- Function/Id instance instance FunArr (->) Identity where toArr = runIdentity f $$ ida = return (f (runIdentity ida)) -- ($$) f = return . f . runIdentity -- The following instance violates the "coverage condition" and so -- requires -fallow-undecidable-instances. instance (FunArr ar w, FunArr ar' w') => FunArr (Pair2 ar ar') (Pair1 w w') where toArr (Pair1 (f,f')) = Pair2 (toArr f, toArr f') Pair2 (f,f') $$ Pair1 (w,w') = Pair1 (f $$ w, f' $$ w')