Friday, September 10, 2010

Memo from head office... Starlings

Memo: Arity families of starlings deemed unnecessary.

...

Often I use an arity family of starling combinators to manipulate records:


star :: (r -> a -> ans) -> (r -> a) -> r -> ans
star2 :: (r -> a -> b -> ans) -> (r -> a) -> (r -> b) -> r -> ans

star comb f1 x = comb x (f1 x)
star2 comb f1 f2 x = comb x (f1 x) (f2 x)


Tracking source position in a parser is a typical example:


-- Example a tracking the source position in a parser:


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


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

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


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


For the 1 arity case, infix obviously works:


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


However, giving `star` the appropriate left fixity means composition works well, removing the need for an arity family:


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


As Applictive's (<*>) is starling for the function instance, I don't even need a new function:


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


Note, I don't use (<$>) and the left hand function has one more argument 's' than usual for the applicative style.

Blog Archive

About Me

My photo
Disambiguating biog as there are a few Stephen Tetley's in the world. I'm neither a cage fighter or yachtsman. I studied Fine Art in the nineties (foundation Bradford 1992, degree Cheltenham 1992 - 95) then Computing part-time at Leeds Met graduating in 2003. I'm the Stephen Tetley on Haskell Cafe and Stackoverflow.