
On 10/16/10 3:39 PM, Stephen Tetley wrote:
Hello list
The Monad and Applicative instances for functions are "equivalent" to the respective Reader vesions (I use "equivalent" along the lines of - operationally the same but without the type distinction / newtype). There is also the Monoid instance for functions which is pretty slick.
Has anyone looked at variations with two or more static arguments though?
For example mappend with two static arguments needs to be defined either as a new function:
mappendR2 :: Monoid a => (r1 -> r2 -> a) -> (r1 -> r2 -> a) -> r1 -> r2 -> a mappendR2 f g = \x y -> f x y `mappend` g x y
or an overlapping instance:
instance Monoid a => OPlus (r1 -> r2 -> a) where f `mappend` g = \x y -> f x y `mappend` g x y
It's not the prettiest, but you can also just make use of uncurrying and have (r1,r2)->a. Via closed cartesian categories, the versions with additional arguments are "uninteresting": which is to say, equivalent to the uncurried version. You may want to introduce a shorthand though, > mappendR2 f g = curry (uncurry f `mappend` uncurry g)
Working in graphics I've found two static arguments comes up quite often - preliminarily most of my functions are functions from the DrawingContext to something (drawing context is an environment that tracks line width, stroke colour, fill colour, etc.): [...] Many of my functions statically use a 'start' point as the only coordinate reference, so they are in a "coordinate free" style:
This sounds like the (r1,r2)->a approach is even reasonable for capturing the actual semantics of your program. Though you may want to rename (Point,DrawingCtx) to something like Coordinateful_DrawingCtx. -- Live well, ~wren