Replies: 1 comment 5 replies
-
|
I can show you with the The first thing to notice from the original signature: hoistFree :: Functor g => (forall a. f a -> g a) -> Free f b -> Free g b... is that there's a It can't be represented in C#. See below, where the asterisks are, they're generic on usage of Free<G, B> Hoist<F, G, B>(Func<F<*>, G<*>> f, Free<F, B> fb)We can get around this though. But we can't use If you know your category-theory, then So, if we create a type called public interface Natural<out F, in G>
{
public static abstract K<G, A> Transform<A>(K<F, A> fa);
}Notice how the We can now implement public static Free<G, B> Hoist<N, F, G, B>(Free<F, B> fb)
where N : Natural<F, G>
where F : Functor<F>
where G : Functor<G> =>
fb switch
{
Pure<F, B>(var x) => Free.pure<G, B>(x),
Bind<F, B>(var xs) => Free.bind(N.Transform(xs).Map(Hoist<N, F, G, B>))
};You'll notice the implementation is almost exactly the same as the Haskell version: hoistFree :: Functor g => (forall a. f a -> g a) -> Free f b -> Free g b
hoistFree _ (Pure a) = Pure a
hoistFree f (Free as) = Free (hoistFree f <$> f as)#The main difference is that Next you'll need to define the natural-transformations for the types that support it. Here's an example of public class OptToSeq : Natural<Option, Seq>
{
public static K<Seq, A> Transform<A>(K<Option, A> fa) =>
fa.As().Match(Some: Seq, None: Seq<A>);
}Then you can invoke it with a lifted functor: var fa = Free.pure<Option, int>(100);
var ga = Hoist<OptToSeq, Option, Seq, int>(fa);I've got some prototypes of a |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Is there a possibility to implement hoistFree, from Haskell free monad in C#?
I've recently found this great project, which, as I found, is doing something I'm implementing myself in order to learn Haskell.
One thing i struggle to implement is aforementioned higher order function, which given a function transforming two different functors of the same type and free monad built upon first functor, produces free monad upon second functor:
hoistFree :: Functor g => (forall a. f a -> g a) -> Free f b -> Free g bMy (not finished) implementation looks like this:
The problem is that compiler does not allow calling fun(res) because it cannot convert from
IKind<TFunctor,Free<TFunctorB, T>>toIKind<TFunctor, V>. Is there a workaround to this?Beta Was this translation helpful? Give feedback.
All reactions