[Haskell-cafe] Re: classes with types which are wrapped in

Stephen Tetley stephen.tetley at gmail.com
Wed Jan 27 04:31:41 EST 2010


2010/1/27 Andrew U. Frank <frank at geoinfo.tuwien.ac.at>:
{Snip]

> dotoBfield :: (b -> b) -> X a b c -> X a b c
> dotoBfield  op x = x { bfield = op (bfield x)}
>
> and similar for A and C.
>
> is there a better idiom to achieve the same effect?
> can this be automated (for example, using generics)?


Hello Andrew

I use a family of variations on the S combinator (also known as
Starling). I wouldn't argue its a better idiom, but I find it
pleasantly regular.

Suppose I had a data type for source positions like Parsec:

> data SrcPos = SrcPos {
>                  src_line       :: Int,
>                  src_column     :: Int,
>                  src_tab_stop   :: Int
>                }

Then update functions on the record follow this pattern

pstar<n> <update-function> (one-or more <selection-function>)


> incrCol :: SrcPos -> SrcPos
> incrCol = pstar (\i s -> s { src_column=i+1 }) src_column

> incrTab :: SrcPos -> SrcPos
> incrTab = pstar2 (\i t s -> s { src_column= (i+t) }) src_column src_tab_stop


> incrLine :: SrcPos -> SrcPos
> incrLine = pstar (\i s -> s { src_line =i+1, src_column=1 }) src_line


At the moment I call the function family 'pstar' for permutated
starlings, but in combinatory logic terms I don't think its strictly
true to consider them permutations so they really need a new name.
Here are the definitions, the order of arguments is changed from
starlings to allow them to be generalized to functors should I need
more generality:


> pstar     :: (a -> r -> ans)
>           -> (r -> a)
>           -> r -> ans
> pstar f fa x = f (fa x) x


> pstar2    :: (a -> b -> r -> ans)
>           -> (r -> a) -> (r -> b)
>           -> r -> ans
> pstar2 f fa fb x = f (fa x) (fb x) x

> pstar3    :: (a -> b -> c -> r -> ans)
>           -> (r -> a) -> (r -> b) -> (r -> c)
>           -> r -> ans
> pstar3 f fa fb fc x = f (fa x) (fb x) (fc x) x

> pstar4    :: (a -> b -> c -> d -> r -> ans)
>           -> (r -> a) -> (r -> b) -> (r -> c) -> (r -> d)
>           -> r -> ans
> pstar4 f fa fb fc fd x = f (fa x) (fb x) (fc x) (fd x) x

> pstar5    :: (a -> b -> c -> d -> e -> r -> ans)
>           -> (r -> a) -> (r -> b) -> (r -> c) -> (r -> d) -> (r -> e)
>           -> r -> ans
> pstar5 f fa fb fc fd fe x = f (fa x) (fb x) (fc x) (fd x) (fe x) x


Best wishes

Stephen


More information about the Haskell-Cafe mailing list