[Haskell-cafe] Systematic treatment of static arguments

wren ng thornton wren at freegeek.org
Sat Oct 16 20:27:19 EDT 2010


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


More information about the Haskell-Cafe mailing list