Re: [Haskell-cafe] Systematic treatment of static arguments

2010-10-17 Thread Erik Hesselink
On Sat, Oct 16, 2010 at 21:39, Stephen Tetley stephen.tet...@gmail.com 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

I think you can just use the original instance for Monoid for this. It declares

instance Monoid b = Monoid a - b

since 'b' can itself be a function (and r1 - r2 - a is parenthesized
as r1 - (r2 - a)), this will work. 'b' can be instantiated to (r2 -
a) in your case, which is a Monoid due to another instance for
functions, this time with 'b' instantiated to 'a'.

This doesn't work for Reader, though. There, you're probably easier
off using just a tuple, or, even better, a record, where you can use
the 'asks' function to extract a single component.

Erik
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Systematic treatment of static arguments

2010-10-17 Thread Stephen Tetley
Hi Erik and wren

Thanks for both messages.

On 17 October 2010 10:12, Erik Hesselink hessel...@gmail.com wrote:
[Snip]

 I think you can just use the original instance for Monoid for this. It 
 declares

 instance Monoid b = Monoid a - b

 since 'b' can itself be a function (and r1 - r2 - a is parenthesized
 as r1 - (r2 - a)), this will work. 'b' can be instantiated to (r2 -
 a) in your case, which is a Monoid due to another instance for
 functions, this time with 'b' instantiated to 'a'.

Thanks - it does work correctly, I was thinking it had to be (r1 - r1
- a), but (r1 - r2 - a) is fine too. Somewhere when I was
experimenting with GHCi, I must have misread an error message to make
me think I needed a new function mappendR2 for (r1 - r2 - a).

 This doesn't work for Reader, though. There, you're probably easier
 off using just a tuple, or, even better, a record, where you can use
 the 'asks' function to extract a single component.


I'm not sure about that one - using a record mandates the upfront work
of a record for each combination and then using Applicative or Monad
combinators with 'asks' for each operation. By extending the
combinator set I can avoid a lot of the clutter from 'asks' but the
downside is I'm introducing my own notation and naming system. Using a
tuple as wren also suggested would probably mean I'd likewise have to
make extensive use of tuple projection functions rather than 'asks'.

I think what I'd doing has similarities to Conal Elliott's 'semantic
editor combinators' so I'll investigate them again, although I feel
Conal's notation is too general for my purposes in this case. Conal
encodes a path directing what the lifted function operates on as
part of each editor, because my paths are shorter and I have fewer
of them I'd prefer to encode them directly as named combinators.

Thanks again

Stephen
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Systematic treatment of static arguments

2010-10-16 Thread Stephen Tetley
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

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.):

fn1 :: DrawingCtx - a

Many of my functions statically use a 'start' point as the only
coordinate reference, so they are in a coordinate free style:

fn2 :: Point - DrawingCtx - a

Some functions even have have a third static argument, for example
drawing arrowheads for lines seems nice if the angle of the line is
parametric and not used explicitly:

fn3 :: Radian - Point - DrawingCtx - a

The help from Applicative, Monad and Monoid is used up by the one
static argument version, so I find that I have to introduce points (in
the pointed / point-free sense not in the graphic sense) in the fn2
and fn3 versions where a point-free version might still be nice.

Is there any prior work looking at sets of combinators for these
higher arity functions - papers or code? I'd prefer not to introduce a
whole new lexicon of combinator names if I can help it.

Thanks

Stephen
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Systematic treatment of static arguments

2010-10-16 Thread wren ng thornton

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
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe