Yesterday's Wikibender that started with this stackoverflow qestion on Comonads ended up at MarkCC's article on Finger Trees.
In the article he makes extensive use of the Reduce type class. He writes about this typeclass as if it is a very common and frequently use library, but I cannot find it on hackage, nor can I find enough documentation to really understand the code.
Can someone help me understand what the Reduce typeclass is doing, how the (-<) and (>-) operators work, and what should tell me about the code in the article (copied below)?
Code Listing from Finger Trees Done Right (I hope):
Listing 1: instance declaration for Node
instance Reduce Node where
reducer (-<) (Node2 a b) z = a -< (b -< z)
reducer (-<) (Node3 a b c) z = a -< (b -< (c -< z))
reducer (>-) (Node2 b a) = (z >- b) >- a
reducer (>-) (Node3 c b a) = ((z >- c) >- b) >- a
Listing 2: instance declaration for FingerTree
instance Reduce FingerTree where
reducer (-<) Empty zero = zero
reducer (-<) (Single x) zero = x -< zero
reducer (-<) Deep left mid right zero = left -<' (mid -<'' (right -<' zero))
where (-<') = reducer (-<)
(-<'') = reducer (reducer (-<))
reducel (>-) zero Empty = zero
reducel (>-) zero (Single x) = zero >- x
reducel (>-) zero (Deep left mid right) = ((zero >-' left) >-'' mid) >-' right
where (>-') = reducel (>-)
(>-'') = reducel (reducel (>-))
listing 3: data types
data Node s = Node2 s s | Node3 s s s
data FingerTree a = Empty
| Single a
| Deep (Digit a) (FingerTree (Node a)) (Digit a)
data Digit a = [ a ]
Given that
reduceis a common alternate name for a "fold" function, I'd guess that it's something similar to theFoldabletype class. The instance definitions seem to make sense as such, as well.The
Foldableclass can be defined using justfoldr, which has the type signaturefoldr :: (Foldable t) => (a -> b -> b) -> b -> t a -> b, whereas thereducerin that code appears to bereducer :: (Reduce t) => (a -> b -> b) -> t a -> b -> b. Other than a different argument order, it should work the same.Note that the operators are just arguments to the function--you could replace them all with
for another similarly generic identifier. Using an operator as the name of a binary function argument is... a slightly unusual choice, but it does emphasize some aspects of the structure of the fold, I guess.