2

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

7.12 Explicit polymorphic type annotations

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 

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

+1

Вы хотели написать let rec tmap: 'a. 'a t -> (' a -> 'b) ->' b t = fun f -> function ...? – camlspotter

ответ

2

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

В глубине 'b не является полиморфным. Кроме того, вы можете удалить это упоминание -rectypes сейчас :-) – PatJ

+0

yep, fixed. Мы это сделали! – ivg

+0

Существует еще '' b' в 'depth', который вызывает ошибку типа ... – PatJ

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 должен быть полиморфным тоже, как вы хотите создать вложенные кортежи до тех пор, как вы спускаетесь по дереву.

Это должно быть, благодаря ИДК:

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

Это всего лишь неправильный синтаксис для аннотации типа, parens in the place place =) – ivg

+0

Исправлено. Мне очень нужно спать -_-, – PatJ

+0

меня тоже, я пропустил '' b'' – ivg

0

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

let int_tree = Node (Узел (Лист ((3, -1), (0,4)))) ;;
let char_tree = Node (Узел (Лист (('a', 'c'), ('d', 'c')))) ;;

tmap int_tree ~ f: (fun x -> x * x) ;;
-: INT т = Узел (Node (листьев ((9, 1), (0, 16))))

TMAP char_tree ~ F: (весело х -> Char.uppercase х) ;;
-: char t = Узел (Узел («A», «C»), ('D', 'C'))))

 Смежные вопросы

  • Нет связанных вопросов^_^