Определение типа функции OCaml

Я хочу написать функцию типа

int -> 'a -> (int, int) slowa list

Мне было интересно, мне обязательно нужно сначала определить тип slowa

Если так, то так я определил свою "медлительность"

    type slowa = 
    (_,_)
    |('a, 'b) of int * int
;;

куда slowa имеет тип (int, int)Но я не уверен, как, если я думаю правильно. Буду признателен за помощь. Я новичок в этом:)

РЕДАКТИРОВАТЬ: Итак, теперь я пошел, чтобы попробовать это:

type ('b, 'a) slowa = int * 'b
let c = 3, 5;;
let d = 1, 3;;

let rec add k v d =
    match d with
    | [] -> [(k,  v)]
    | (k', v')::t ->
        if k = k'
        then (k, v) :: t
        else (k', v') :: add k v t
        ;;

но я хочу это тип функции add чтобы быть как этот тип: int -> 'a -> (int, int) slowa list

Было бы проще, если бы я хотел просто вернуться list но теперь возвращаемый тип int -> 'a -> (int, int) slowa list это сбивает с толку...:/ Я верен в отношении количества / типа параметров.

1 ответ

Решение

Если вы просто хотите тип, который является синонимом для int * int (пары целых), вы можете определить это так:

type slowa = int * int

В этом случае имя является просто синонимом. Вы всегда можете заменить использование имени определением. Таким образом, вам на самом деле не нужно давать определение (это хорошо для документации).

Если вы хотите определить новый тип, вам нужно определить конструктор для него:

type myslowa = Slow of int * int

Это определяет новый тип. Значения типа выглядят как Slow (3, 4), Эти значения имеют тип, отличный от всех остальных; то есть они не взаимозаменяемы с парами целых.

Если вы хотите определить параметризованный тип, вам нужно включить параметр (ы) в ваше определение:

type ('a, 'b) pslowa = 'a * 'b

Поскольку нового конструктора нет, это также просто синоним. Но это синоним бесконечного набора типов. В частности, это синоним для пар любых двух типов.

Если вы хотите определить новыйпараметризованный тип, вам нужно иметь как параметры, так и конструктор:

type ('a, 'b) mypslowa = Slow of 'a * 'b

Это сочетает в себе свойства; т.е. это новый тип, который представляет пары любых двух типов.

Надеюсь, это поможет; один из них может быть близко к тому, что вы ищете.

Обновить

С вашим новым определением slowaтип (int, int) slowa идентичен типу int * int, Когда верхний уровень показывает вам тип чего-либо, он должен выбирать среди всех способов представления типа. Я думаю, что вы говорите, что верхний уровень выбирает использовать int * int скорее, чем (int, int) slowa, Лучше не зацикливаться на этом (ИМХО). Единственное, что вы можете попробовать, это аннотировать ваши типы:

type ('b, 'a) slowa = int * 'b
let c = 3, 5;;
let d = 1, 3;;

let rec add k v (d: ('a, 'b) slowa list) : ('a, 'b) slowa list =
    match d with
    | [] -> [(k,  v)]
    | (k', v')::t ->
        if k = k'
        then (k, v) :: t
        else (k', v') :: add k v t
        ;;

(Ваше определение slowa выглядит немного странно, так как вы не используете параметр для чего-либо.)

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