Well, that they are heavily used in practice does not mean that they are actually useful in practice. The thing is that as soon as your functor is a monad, I don't think you really need the Free type anymore -- your instruction type is already a monad.
(But I think it will be impossible for MonadCont).
Almost, but not quite. The key qualification is "while still allowing pattern matching".
To summarize, I currently don't see what 'free' offers that the 'operational' package can't do equally well with only 11 exported symbols.
Nickolay Kudasov wrote:Well, that they are heavily used in practice does not mean that they are actually useful in practice. The thing is that as soon as your functor is a monad, I don't think you really need the Free type anymore -- your instruction type is already a monad.
In the 'free' approach, I find it unpleasant that some laws are
automatic from the functor type, while others have to be ensured by the
interpreter. That's why 'operational' offers only one way to implement
monads: everything has to be done in the interpreter.
As far as I know these instances are heavily used in practice, though they
are inconvenient in a way. Perhaps they could be moved in a separate
module. On the other hand one could use `FreeT` which derives instances in
a different manner.
Ah, I see now. Yes, it is possible for all classes that don't have control operations. (But I think it will be impossible for MonadCont).
If you look at the transformer version Control.Monad.Trans.Free , you
will see that there are no MonadState instances -- as expected, because you
have to specify the interaction of effects.
Some instances are present in HEAD [1], just not on hackage yet. Some
other instances (MonadCont [2], MonadWriter [3]) are waiting for Edward
Kmett's approval.
And looking at my 'operational' package, it appears that ProgramT already includes the desired MonadState and MonadIO instances! In other words, 'operational' had always included proper support for monad transformer stacks.
(The MonadReader class has a control operation, local , but looking at the source for FreeT , it appears that it can actually be lifted. Amazing!)
Note that `Free` does not have "the true" set of mtl instances. While these
instances (derived from underlying functor) are heavily used in practice
for `Free`, `FreeT` suggests deriving instances from the transformed monad
(not underlying functor). It turns out the latter can be done for the most
part of MonadX instances (MonadWriter instance is somewhat questionable).
See some comments in [4].
That said, as we saw, Free can give you some laws automatically. However,
this also has a drawback: Program has an optimization that Free can never
have. Namely, Program gives you a (>>=) that can be used in a
left-associative way (Think (((x ++ y) ++ z) ++ w) ) while still allowing
pattern matching.
As far as I can tell, this corresponds to church encoded versions of `Free`
and `FreeT`, namely `F` and `FT`.
This is possible due to the work "Asymptotic Improvement of Computations
over Free Monads" by Janis Voightländer [5] and based on Edward Kmett's "Free
Monads for Less" series of articles [6,7]. `F` is on hackage already and
`FT` is in HEAD.
Almost, but not quite. The key qualification is "while still allowing pattern matching". The church encoding is akin to difference lists: you get O(1) (++), but now head and tail are O(n) .
In contrast, Program represents lists of instructions in a way similar to
data List a = Nil | One a | Concat (List a) (List a)
This gives you O(1) append and head / tail if used in an ephemeral fashion. (It is actually possible to turn this into a genuine O(1) head and tail, but it's not worth it.) You can't do this optimization in Free.
To summarize, I currently don't see what 'free' offers that the 'operational' package can't do equally well with only 11 exported symbols.
Best regards,
Heinrich Apfelmus
--
http://apfelmus.nfshost.com
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe