Объявление типа функции в SML - PullRequest
0 голосов
/ 03 марта 2019

Я новичок в ML, но на других языках, которые используют вывод типов, я научился опускать тип вещи всякий раз, когда вывод с правой стороны очевиден для читателя, и явно объявлятьтип вещи всякий раз, когда вывод не очевиден для человека.Мне нравится это соглашение, и я хотел бы продолжить его в своем коде ML.

У меня есть следующие примеры объявлений функций, которые эквивалентны:

fun hasFour      [] = false
  | hasFour (x::xs) = (x = 4) orelse hasFour xs

эквивалентно

val rec hasFour: int list -> bool =
 fn      [] => false
  | (x::xs) => (x = 4) orelse hasFour xs

Мне нравится последняя форма не только потому, что мне легче выяснить, какого типа функция, когда я ее читаю, но и потому, что она явно объявляет тип функции и, следовательно, если я что-то прикручиваюв моей реализации, нет никакого шанса случайно объявить что-то, что синтаксически допустимо, но неправильный тип, который труднее отладить позже.

Мой вопрос: я хочу использовать fun вместо val recпотому что анонимные fn могут принимать только один параметр.Таким образом, последний метод синтаксически недопустим для такой функции, как int -> int -> bool.Есть ли способ явно объявить тип в fun?Или я назвал все предпочтительные альтернативы в этом посте, и должен просто следовать одному из этих шаблонов?Единственный способ найти fun с явным объявлением типа - добавить объявление типа к каждому параметру в шаблоне, что выглядит ужасно и ужасно, например:

fun hasFour ([]:int list):bool = false
  | hasFour            (x::xs) = (x = 4) orelse hasFour xs

Один из коллег показалВот некоторый код, следующий за шаблоном, подобным этому:

fun hasFour      [] = false
  | hasFour (x::xs) = (x = 4) orelse hasFour xs

val _ = op hasFour: int list -> bool

Объявляя неназванную переменную и присваивая ей экземпляр функции с принудительным типом, мы эффективно достигаем желаемого результата, но val _ долженпоявится ниже полностью определенной функции, где она менее очевидна для читателя, если вы просто не привыкнете к этому шаблону и не научитесь ожидать его.

1 Ответ

0 голосов
/ 04 марта 2019

Я задал очень похожий вопрос, Можно ли аннотировать полный тип объявления fun? , недавно.

Ваше текущее решение было быхороший ответ на этот вопрос.

У вас может быть несколько аргументов карри с несколькими fn, например:

val rec member : ''a -> ''a list -> bool =
    fn x => fn [] => false
             | y::ys => x = y orelse member x ys

Или вы можете делать то, что делаете сейчас, или как подсказывает Мэтт:

local
  fun member _ [] = false
    | member x (y::ys) = x = y orelse member x ys
in
  val member = member : ''a -> ''a list -> bool
end

Но комбинация использования fun и наличия полной сигнатуры типа в списке пока неясна.

Для производственного кода нормой являетсядля сбора сигнатур типа в сигнатуре модуля .См. ML для рабочего программиста, гл.7 : Подписи и абстракция , с. 267-268.Хотя я думаю, что вы захотите использовать Ocaml тогда.

...