我试图翻译这段描述List anamorphism的Haskell代码,但不能完全让它工作。
最后三行应该是生成一个函数计数,给定一个int将产生一个int列表[n,n-1,...,1]。
Haskell代码。
data Either a b = Left a | Right b
type List_coalg u x = u -> Either () (x, u)
list ana :: List_coalg u x -> u -> [x]
list_ana a = ana where
ana u = case a u of
Left _ -> []
Right (x, l) -> x : ana l
count = list_ana destruct_count
destruct_count 0 = Left ()
destruct_count n = Right (n, n-1)
目前我所掌握的情况:
type ('a, 'b) List_coalg = 'a -> (unit, 'a*'b) Either
fun list_ana (f : ('a, 'b) List_coalg) : 'a -> 'b list =
let
fun ana a : 'b list =
case f a of
Left () => []
| Right (x, l) => x :: ana l
in
ana
end
fun destruct_count 0 = Left ()
| destruct_count n = Right (n, n-1)
val count = list_ana destruct_count
我得到了以下错误。
catamorphism.sml:22.7-24.35 Error: case object and rules do not agree [UBOUND match]
rule domain: (unit,'b * 'a) Either
object: (unit,'a * 'b) Either
in expression:
(case (f a)
of Left () => nil
| Right (x,l) => x :: ana l)
不知道如何解决这个问题,因为我对SML不是很精通。
正如你在注释中提到的,类型参数被混淆了。通过一点重命名来比较。
type List_coalg a b = a -> Either () (b, a) -- (b, a)
type ('a, 'b) List_coalg = 'a -> (unit, 'a*'b) Either (* ('a * 'b) *)
导致在模式匹配后出现了不匹配的情况
Right (x, l) -> x : ana l
-- x :: b
-- l :: a
Right (x, l) => x :: ana l
(* x : 'a *)
(* l : 'b *)