
Hello all For manipulating records I use an arity family of so-called "Starling" combinators - they seem a pleasant if low-powered solution. To me, the infix combinator style of Data-Accessor quickly ends up looking like a particulary angry exchange between Snoopy and Woodstock[1].
star :: (a -> r -> ans) -> (r -> a) -> r -> ans star2 :: (a -> b -> r -> ans) -> (r -> a) -> (r -> b) -> r -> ans star3 :: (a -> b -> c -> r -> ans) -> (r -> a) -> (r -> b) -> (r -> c) -> r -> ans star4 :: (a -> b -> c -> d -> r -> ans) -> (r -> a) -> (r -> b) -> (r -> c) -> (r -> d) -> r -> ans star5 :: (a -> b -> c -> d -> e -> r -> ans) -> (r -> a) -> (r -> b) -> (r -> c) -> (r -> d) -> (r -> e) -> r -> ans
star f fa x = f (fa x) x star2 f fa fb x = f (fa x) (fb x) x star3 f fa fb fc x = f (fa x) (fb x) (fc x) x star3 f fa fb fc fd x = f (fa x) (fb x) (fc x) (fd x) x ....
An example - tracking the source position in a parser:
data SrcPos = SrcPos { src_line :: Int, src_column :: Int, src_tab_size :: Int }
incrCol :: SrcPos -> SrcPos incrCol = star (\i s -> s { src_column=i+1 }) src_column
incrTab :: SrcPos -> SrcPos incrTab = star2 (\i t s -> s { src_column=i+t }) src_column src_tab_size
incrLine :: SrcPos -> SrcPos incrLine = star (\i s -> s { src_line =i+1, src_column=1 }) src_line
[1] For those missing the cultural reference, in the UK and USA cartoon characters usually have swearing censored with sequences of non-alpha characters, e.g. "What the @#*&! ?"