#f#
Вопрос:
Как пользователь файла подписи .fsi, какая разница, если таковая имеется, существует между:
val sum : int -> int -> int
и
val sum : (int -> int -> int)
Похоже, что второе может быть реализовано с помощью определения функции или с помощью псевдонима функции, но первое может быть реализовано только с помощью определения функции.
Со следующими:
// .fsi
val add : int -> int -> int
val sum : int -> int -> int
// .fs
let add a b = a b
let sum = add
генерируется ошибка
error FS0034: Module 'Butter' contains
val sum : (int -> int -> int)
but its signature specifies
val sum : int -> int -> int
однако, если файл подписи является:
// .fsi
val add : (int -> int -> int)
val sum : (int -> int -> int)
он компилируется нормально.
Является ли такое поведение преднамеренным, и если да, то как круглые скобки изменяют интерфейс?
Ответ №1:
Что здесь за Кортеж? Если это .NET System.Tuple
, то это не имеет смысла.
val x : Tuple -> float
Будет функцией, которая принимает кортеж статического класса и возвращает значение с плавающей точкой. Если вам нужен экземпляр кортежа, вам нужно будет точно указать, какой тип n-кортежа вы хотите ( Tuple<'a>
и Tuple<'a, 'b>
это два разных типа).
Должно сработать следующее:
var x : Tuple<float, _, _, _> -> float
Комментарии:
1. Спасибо тебе, Том. Мое включение
Tuple
в пример делает излишне запутанным, что этот кортеж является типом домена, не связанным с кортежами языка. Но чтобы дважды проверить, что это не проблема, и чтобы уменьшить путаницу, я воссоздал проблему с помощью гораздо более простого кода. Я обновлю свой вопрос и тоже планирую загрузить демо-код. (Исходный код предназначен для «Задачи трассировки лучей».) Спасибо.
Ответ №2:
Да, это преднамеренное поведение.
Создавая более простой пример в ответ на ответ Тома, я на самом деле правильно прочитал сообщение об ошибке, в котором говорится:
Различия в подписи и реализации различаются. Подпись указывает, что «сумма» — это определение функции или лямбда-выражение, принимающее по крайней мере 2 аргумента(аргумента), но реализация представляет собой вычисленное значение функции. Чтобы объявить, что вычисляемое значение функции является разрешенной реализацией, просто заключите его тип в скобки в подписи, например↔ сумма значений: int -> (int ->> int)↔вместо↔ сумма значений: int ->>> int ->>>> int.
Таким образом, скобки используются для обозначения того, что вычисляемое выражение является допустимой реализацией, а также определениями лямбд и функций. (Я не буду притворяться, что правильно понимаю разницу.)