前回および前々回の投稿に引き続いて。
正直問題ないのかよく分かりませんな。具体例を当てはめてやらないとダメですね。
// 前回および前々回の定義を前提としています。
type ProdF<'c,'a,'x> =
| ProdF of 'a * F<'x>
interface F<'c> with
member x.fmap f p =
let rec fmap0 (f:'b -> 'd) (p : F<'b>) =
match p :?> ProdF<'b,'a,'y> with
| ProdF(a, fx) -> ProdF(a, fmap0 f fx) :> F<'d>
fmap0 f p
let forkF f g x =
ProdF(x |> fork f g)
let hdCV (xs : Nu<ProdF<'c,'a,'x>>) =
match (out xs) :?> ProdF<Nu<ProdF<'c,'a,'x>>,'a,'x> with
| ProdF(c, _) -> c
let tlCV (xs : Nu<ProdF<'c,'a,'x>>) =
match (out xs) :?> ProdF<Nu<ProdF<'c,'a,'x>>,'a,'x> with
| ProdF(_, fx) -> fx
let rec histo phi x =
let y = unIn x
y
|> y.fmap (ana (fun z -> (forkF (histo phi) unIn z) :> F<Mu<'c>>))
|> phi
type SumF<'c,'a,'x> =
| SumF of Sum<'a, F<'x>>
interface F<'c> with
member x.fmap f p =
let rec fmap0 (f:'b -> 'd) (p : F<'b>) =
match p :?> SumF<'b,'a,'b> with
| SumF(InL(a)) -> SumF(InL(a)) :> F<'d>
| SumF(InR(x)) -> SumF(InR(fmap0 f x)) :> F<'d>
fmap0 f p
let joinF f g s =
match s with
| SumF s0 -> join f g s0
let lastF (x : 'a) : Mu<SumF<'c,'a,'x>> = In (SumF (InL x))
let consF (x : F<Mu<SumF<'c,'a,'x>>>) : Mu<SumF<'c,'a,'x>> = In (SumF (InR x))
let rec futu (phi : 'a -> F<Mu<SumF<'c,'a,'x>>>) (x : 'a) =
let y = phi x
y
|> y.fmap (cata (fun z -> (joinF (futu phi) Wrap) (z :?> SumF<Nu<'a>,'a,Nu<'a>>)))
|> Wrap