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.
-
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 b
My (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