Type-safe Transducers in Clojure, Scala, and Haskell
blog.podsnap.com
blog.podsnap.com
[1] https://github.com/clojure/clojure/blob/b01adb859c66322c5cff...
[2] https://github.com/clojure/clojure/blob/b01adb859c66322c5cff...
Couldn't you just parametrize over IO/ST/etc.? E.g. something like
IO r -> a -> IO r
I don't have a great mental model of transducers yet, so I'm not confident about that. data Fold i o = forall st . Fold
{ merge :: st -> i -> st
, this :: st
, view :: st -> o
}
type (i ~> o) = forall r . Fold o r -> Fold i r
-- compare
type Trans i o = forall r . (r -> o -> r) -> (r -> i -> r)
Now each "step" has local pure state and no other step can break abstraction barriers and view it. This also gives you all of the effects of the indexed state passing Rich called untypeable.Fold is equivalent to an infinite state Moore machine, so a stack of composed transducers applied to a base Moore machine which produces whatever result you want can be compiled a really efficient form.
Early termination can be done by changing `merge` to `merge :: st -> i -> Either o st`.
(b -> IO a) -> [b] -> IO [a]
instead of (a -> b -> a) -> a -> [b] -> [a]
Just putting the whole thing in the IO/ST monad isn't the right solution when you need a very specific form of local state.