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