Подпись объявления функции в Ocaml - PullRequest
1 голос
/ 18 июля 2011

Я определил функцию, подобную следующей:

let ff (f1: a_function) (f2: a_function) (v0: type1) (v1: type2): type3 = ...

И другая функция, подобная следующей, работает:

let f: type1 -> type2 -> type3 = ff f1 f2

Но другое объявление, подобное следующему, не работает:

let f (v0: type1) (v1: type2): type3 = ff f1 f2

Сообщение об ошибке:

Error: This expression has type
         type1 -> type2 -> type3
       but an expression was expected of type type3

Я всегда думал, что let f: type1 -> type2 -> type3 совпадает с let f (v0: type1) (v1: type2): type3.Может кто-нибудь сказать мне, почему первое объявление работает, но не второе?

Большое спасибо

PS1: Мой ключевой вопрос, учитывая let f (v0: type1) (v1: type2): type3 = ff f1 f2, не 'т тип f type1 -> type2 -> type3?

Если let f (v0: type1) (v1: type2): type3 = ff f1 f2 и let f (v0: type1) (v1: type2): type3 = ff f1 f2 возвращают одинаковый тип f, в чем разница между этими двумя сигнатурами?

Ответы [ 2 ]

3 голосов
/ 18 июля 2011

Что ж, в вашем определении f вы говорите, что оно принимает два аргумента типов type1 и type2 и возвращает результат типа type3.Так что тело должно иметь type3.Вместо этого он имеет тип type1 -> type2 -> type3, как вы можете видеть из определения f, и именно это говорит вам компилятор.

Возможно, вы имели в виду:

let f (v0: type1) (v1: type2): type3 = ff f1 f2 v0 v1

Учитывая ваш PSтип f не тот, что вы говорите, потому что f не проверяет тип.Я пытался ответить, почему выше.Если вы опустите тип возврата f, например:

let f' (v0: type1) (v1: type2) = ff f1 f2

, тогда тип f' будет type1 -> type2 -> type1 -> type2 -> type3.

.
0 голосов
/ 18 июля 2011

Аргументы v0, v1 вашего второго определения висят.С другой стороны, это объявление работает:

module type TimurTest =
  sig
    type type1
    type type2
    type type3
    type functional1
    type functional2
    val f1 : functional1
    val f2 : functional2
    val ff : functional1 -> functional2 -> type1 -> type2 ->type3
  end

module MyTest(M:TimurTest) =
  struct
    let f : M.type1 -> M.type2 -> M.type3 = M.ff M.f1 M.f2
    let f (v0: M.type1) (v1: M.type2) : M.type3 = M.ff M.f1 M.f2 v0 v1
    let g (v0: M.type1) (v1: M.type2) = M.ff M.f1 M.f2
  end

Последняя строка отвечает вашему PS (обратите внимание, что я не указал тип возврата g, чтобы компилятор мог сделать вывод, каким он должен быть):поскольку его определение игнорирует аргументы v0 и v1, значение curry для g (v0:type1) (v1:type2) = ff f1 f2 дает ему тип type1 -> type2 -> type1 -> type2 -> type3.По сути, вам требуются два дополнительных аргумента, значение которых вы собираетесь отбросить (не передавая их в ff f1 f2, что потребует двух своих собственных).

И действительно, при объявлении вышеуказанного модуля часть ответа компилятора выглядит так:

      val g : M.type1 -> M.type2 -> M.type1 -> M.type2 -> M.type3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...