3 ms·
This sort of reminds me of the Church-encoded form of a list. newtype Fold a = Fold (forall r . (a -> r -> r) -> r -> r) fold :: [a] -> Fold a fol
by tel 12y ago
This sort of reminds me of the Church-encoded form of a list.
newtype Fold a = Fold (forall r . (a -> r -> r) -> r -> r)
fold :: [a] -> Fold a
fold xs = Fold (spin xs) where
spin [] cons nil = nil
spin (a:as) cons nil = cons a (spin as cons nil)
refold :: Fold a -> [a]
refold (Fold f) = f (:) []
Notably, since `fold` and `refold` are isomorphisms then we can do everything we can do to `[a]` to `Fold a`
map :: (a -> b) -> (Fold a -> Fold b)
map x (Fold f) = Fold $ \cons nil -> f (cons . x) nil
filter :: (a -> Bool) -> Fold a -> Fold a
filter p (Fold f) =
Fold $ \cons nil -> f (\a r -> if p a then cons a r else r) nil
but all of this work is done without concrete reference to `(:)` and `[]`... you instead just use stand-ins I've been calling cons and nil. What's nice about this is that `Fold` can be used to build anything which can be "constructed from the left"
foldSet :: Fold a -> Set a
foldSet (Fold f) = f Set.insert Set.empty
It's sort of dual to the stuff I was exploring in Swift here [0]. It also creates laziness for free because you can't really execute the chain until the end—Church-encoding is really a form of continuation passing.
The downside of this idea is that each time you "consume" a Fold you redo work—there's no place to put caching necessarily.
Maybe that's what they're solving with the Fold transformers representation.
[0] http://tel.github.io/2014/07/30/immutable_enumeration_in_swift/ http://tel.github.io/2014/07/30/immutable_enumeration_in_swi...
- richhickey 12y agoKind of. The idea is to get out of the context of the 'whole job' (the ->r->r bit above) and focus on transformations of the step function (a->r->r) -> (b->r->r) {using your arg order above}. Not talking about the whole job (i.e. the source and result) makes for much more highly reusable components, especially when the jobs don't produce concrete results but, e.g., run indefinitely, like channel transformations.
- tel 12y agoYeah, I'm less sure about the properties as you go this way. You ought to be able to get an Arrow out of it and it's a pretty natural idea.
- lmm 12y agoSo is this actually just the Free monad?
- tel 12y agoNo, it's kind of a universal construction though, but not in any way more special than regular lists are.
- wyager 12y agoFor those curious a about this, look up Haskell's `build` and `destroy` functions. Those functions are for church-encoding lists and doing optimizations that way.
- avernet 12y agoHere is a link: http://www.haskell.org/haskellwiki/Correctness_of_short_cut_fusion http://www.haskell.org/haskellwiki/Correctness_of_short_cut_...