{-# OPTIONS -Wall #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Aviary -- Copyright : (c) Stephen Peter Tetley 2009 -- License : BSD3 -- -- Maintainer : stephen.tetley@gmail.com -- Stability : experimental -- Portability : to be determined -- -- Plainly named combinators -- -- Sometimes permuted to be generally useful... -- -- Note the fixity of @(\#)@ and @(\#\#)@ is not yet /fixed/. -- Some experience needs to be gathered as to whether the -- precendence levels are appropriate. -- ----------------------------------------------------------------------------- module Data.Aviary ( -- * The real stuff ( # ) , ( ## ) , subst , bigphi , appro , dup -- * Specs , oo , ooo , oooo -- * Combiners , combfi , combfii , combfiii ) where import Data.Function -------------------------------------------------------------------------------- -- Combinators infixl 7 # -- | T combinator - thrush -- -- Reverse application - the T combinator. -- Found in Peter Thiemann's WASH and the paper 'Client-Side Web -- Scripting in Haskell' - Erik Meijer, Daan Leijen & James Hook. -- ( # ) :: a -> (a -> b) -> b x # f = f x infixl 8 ## -- | Q Combinator - the queer bitd. -- -- Reverse composition - found in Peter Thiemann's WASH. -- You might perfer to use (<<<) from Control.Categoty. -- ( ## ) :: (a -> b) -> (b -> c) -> a -> c f ## g = \x -> g (f x) -- | S combinator - subst. -- Familiar as Applicative\'s ('<*>') operator, which itself is -- fmap: -- -- f (b -> c) -> f b -> f c where f = ((->) a) subst :: (a -> b -> c) -> (a -> b) -> a -> c subst f g x = f x (g x) -- | The big Phi, or Turner's @S'@ combinator. -- Known to Haskell programmers as liftA2 and liftM2 for the -- Applicative and Monad instances of (->). -- -- > (a1 -> a2 -> r) -> m a1 -> m a2 -> m r where m = ((->) a) -- -- Taste suggests you may prefer liftA2 especially as @bigphi@ is -- not a great name (calling it s\' would take a very useful -- variable name). -- bigphi :: (b -> c -> d) -> (a -> b) -> (a -> c) -> a -> d bigphi f g h x = f (g x) (h x) -- | A variant of the @D2@ or dovekie combinator - the argument -- order has been changed to be more satisfying for Haskellers: -- -- > (appro comb f g) x y -- -- > (f x) `comb` (g y) -- -- @on@ from Data.Function is similar but less general, where -- the two intermediate results are formed by applying the same -- function to the supplied arguments: -- -- > on = (appro comb f f) -- appro :: (c -> d -> e) -> (a -> c) -> (b -> d) -> a -> b -> e appro comb f g x y = comb (f x) (g y) -- | dup - duplicator aka the W combinator aka Warbler. -- -- > dup f x = f x x -- dup :: (a -> a -> b) -> a -> b dup f x = f x x -------------------------------------------------------------------------------- -- Specs - blackbird, bunting, ... -- Alleviate your composing-sectioning mania with specs! -- -- E.g.: -- (abs .) . (*) ==> abs `oo` (*) -- -- The family name /specs/ (glasses, specs, lunettes) is a -- visual pun when infix directives @`oo`@ are included. The -- @o@\'s of individual combinators are a fraternal nod to -- Clean and ML who use @o@ as function composition. Naturally -- we don\'t defined @o@ here and waste a good variable on a -- redundant combinator. -- | Compose an arity 1 function with an arity 2 function. -- B1 - blackbird oo :: (c -> d) -> (a -> b -> c) -> a -> b -> d oo f g = (f .) . g -- | Compose an arity 1 function with an arity 3 function. -- B2 - bunting ooo :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e ooo f g = ((f .) .) . g -- | Compose an arity 1 function with an arity 4 function. oooo :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f oooo f g = (((f .) .) .) . g -------------------------------------------------------------------------------- -- Combiners -- | Combiners - similar to the cardinal\' combinator. -- -- Mnemonically - @comb@(ine) after applying @f@ to @x@ and a -- single identity: @y@. -- -- > combfi comb f x y = comb (f x) y -- -- Equivalently: -- -- > combfi comb f = appro comb f id -- -- But combfi is a useful introduction to the (somewhat manic, -- but sometimes useful) higher arity versions. -- combfi :: (c -> b -> d) -> (a -> c) -> a -> b -> d combfi comb f x y = comb (f x) y -- | Extrapolation of 'combfi' with another identity. -- -- Mnemonically - comb(ine) after applying @f@ to @x@ and two -- identities: @y@ and @z@. -- -- > combfii comb f x y z = comb (f x) y z -- combfii :: (d -> b -> c -> e) -> (a -> d) -> a -> b -> c -> e combfii comb f x y z = comb (f x) y z -- | Extrapolation of 'combfii' with a further identity. -- -- Mnemonically - comb(ine) after applying @f@ to @s@ and three -- identities: @t@ and @u@ and @v@. -- -- > combfii comb f s t u v = comb (f s) t u v -- combfiii :: (e -> b -> c -> d -> f) -> (a -> e) -> a -> b -> c -> d -> f combfiii comb f s t u v = comb (f s) t u v