OCaml Явные аннотации полиморфного типа

Я хотел бы получить некоторые полезные комментарии, касающиеся примера, приведенного на:
http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html

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

что я не совсем понимаю. Буду признателен за любой полезный комментарий.

3 ответа

Вы забыли получить второй аргумент.

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

У вас есть несколько проблем, например, неправильно поставленные круглые скобки 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)))

Большое спасибо за вашу большую помощь Теперь мои тесты работают так, как задумано:

let int_tree = Node (Node (Leaf ((3, -1), (0,4))));;
let char_tree = Node (Node (Leaf (('a', 'c'), ('d', 'c'))));;

tmap int_tree ~ f: (весело x -> x * x);;
-: int t = Node (Node (Leaf ((9, 1), (0, 16))))

tmap char_tree ~ f: (весело x -> Char.uppercase x);;
-: char t = Node (Node (Leaf (('A', 'C'), ('D', 'C'))))

Другие вопросы по тегам