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

我理解这个示例函数,但是当我尝试定义类型的“类似地图”的函数时

'a. 'a t -> ('a -> 'b) -> 'b t

例如:

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);;

我收到以下错误:

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

我不完全理解。我将不胜感激任何有用的评论。

4

3 回答 3

4

你有一些问题,比如不正确地放置括号f,忘记tmap了分支中函数的参数Node,并且你忘记了'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)))
于 2015-02-17T23:01:17.630 回答
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 ) ;;
于 2015-02-17T23:19:26.653 回答
0

非常感谢您的大力帮助。现在我的测试用例按预期工作:

让 int_tree = Node(Node(Leaf((3,-1),(0,4))));;
让 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'))))

于 2015-02-19T20:39:56.377 回答