OCaml 显式多态类型注释

4

我很乐意听取一个例子的有用评论:
http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html#toc79

7.12 显式多态类型注释

type 'a t = Leaf of 'a | Node of ('a * 'a) t

let rec depth : 'a. 'a t -> 'b = function
|Leaf _ -> 1
| Node x -> 1 + depth x

我理解这个例子函数,但当我尝试定义一个类型为“map-like”的函数时,遇到了困难。
'a. 'a t -> ('a -> 'b) -> 'b t

e.g.:

let rec tmap: 'a. 'a t ->(f:'a->'b) -> 'b t = function
|Leaf x ->  Leaf( f x) 
|Node x -> let res = tmap x in Node(res);;

I get the following error:

Characters 67-77:
  |Leaf x ->  Leaf( f x)
              ^^^^^^^^^^

Error: This expression has type 'c t but an expression was expected of type
         (f:'a -> 'b) -> 'b t

我并不完全理解这个问题。如果有任何有用的评论,我将不胜感激。


1
你想要编写 let rec tmap : 'a. 'a t -> ('a -> 'b) -> 'b t = fun f -> function ... ? - camlspotter
3个回答

4

你有一些问题,比如在f周围放置括号不正确,在Node分支中忘记了tmap函数的参数,并且你忘记了'b的量词。因此,最后在PatJ的帮助下,我们可以写出以下内容:

type 'a t = Leaf of 'a | Node of ('a * 'a) t

let rec depth : 'a. 'a t -> 'b = function
  | Leaf _ -> 1
  | Node x -> 1 + depth x


let rec tmap: 'a 'b. 'a t -> f:('a -> 'b) -> 'b t =
  fun t ~f -> match t with
    | Leaf x -> Leaf (f x)
    | Node x ->
      Node (tmap ~f:(fun (x,y) -> f x, f y) x)

tmap (Node (Leaf (7,8))) ~f:(fun x -> x + 1, x + 2);;
- : (int * int) t = Node (Leaf ((8, 9), (9, 10)))

深入了解,'b不是多态的。此外,您现在可以删除有关-rectypes的提及 :-) - PatJ

4

你忘记获取第二个参数了。

let rec tmap:
 'a. 'a t ->(f:'a->'b) -> 'b t = (* asking for two arguments *)
 function (* takes only the first argument *)
|Leaf x -> Leaf( f x)
|Node x -> let res = tmap x in Node(res);; 

另外,'b 也必须是多态的,因为你想要在遍历树时生成嵌套元组。

感谢 ivg 的帮助,应该可以实现这个功能:

let rec tmap : 'a 'b. 'a t -> f:('a->'b) -> 'b t =  fun t ~f ->
  match t with
  |Leaf x -> Leaf( f x)
  |Node x -> let f (a,b) = (f a, f b) in Node ( tmap x ~f ) ;;

2
这只是类型注释的错误语法,括号放错了位置 =) - ivg
搞定了。我真的需要睡觉 -_-, - PatJ
我也是,我错过了 'b - ivg

0
非常感谢您的大力帮助。 现在我的测试用例已经按照预期工作了: let int_tree = Node(Node(Leaf((3,-1),(0,4))));; let char_tree = Node(Node(Leaf(('a','c'),('d','c'))));;
tmap int_tree ~f:(fun x -> x*x);; - : int t = Node (Node (Leaf ((9, 1), (0, 16))))
tmap char_tree ~f:(fun x -> Char.uppercase x);; - : char t = Node (Node (Leaf (('A', 'C'), ('D', 'C')))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接