Reputation:
Why does Control.Monad.Free
in purescript-free
hide the "view" data structure FreeView
and associated operators toView
etc?
With the usual formulation of a Free Monad -
data Free f a = Pure a | Free (f (Free f a))
And given a Functor such as -
data TeletypeF a = PutStrLn String a | GetLine (String -> a)
I can write some simple (albeit ugly) code to collapse chained PutStrLn calls like so -
collapseChained :: Free TeletypeF a -> Free TeletypeF a
collapseChained (Free (PutStrLn s1 (Free (PutStrLn s2 c)))) = Free PutStrLn (s1 ++ s2) c
collapseChained f = f
Is something equivalent to collapseChained
possible using the functions exported by Purescript's Control.Monad.Free
, without using any actual data constructors?
Upvotes: 2
Views: 440
Reputation: 4649
I tried for a while to do this with runFreeM
and the like but without success, so no, I don't think it is possible to a transformation directly like this.
The usual formulation of Free
you mention is unsuitable for use in PureScript as it cannot be made stack safe, so unfortunately direct manipulation of the tree is obscured. The constructors are not exported at all now as we're using internal unsafe coercions to make the implementation possible in the style of Reflection without Remorse.
We previously had a slightly different implementation without coercions that was similar to the scalaz Free
, as that also requires a stack safe implementation, but I think this would have had the same problem also.
Maybe if we exposed more internals (fromView
, toView
, etc.) it would be possible, but it still be less pleasant than the direct pattern matching approach, and I think exposing those may have safety issues.
Upvotes: 1