Как уже упоминалось, в ocaml переменная типа 'a,' b и т. Д. Означает «для всех типов, как определено компилятором». Простейшим случаем является функция тождества (функция, которая просто возвращает свой аргумент), которая может принимать и возвращать любой тип, и чей аргумент и тип возвращаемого значения могут поэтому обозначаться переменной типа 'a. Или список или массив может содержать любой тип, поэтому функции, возвращающие списки или массивы, могут иметь тип 'список или' массив.
Но многие проблемы не могут быть решены "для всех типов", а именно там, где код написано специфицируется c для определенного типа или конкретных типов. Как уже упоминалось, функция идентификации может принимать и возвращать любой тип. Но, например, функция, которая умножает свой аргумент на 2 и возвращает продукт, должна взять и вернуть число, либо int, либо float. Кроме того, в ocaml есть отдельные операторы для умножения чисел и чисел с плавающей запятой: поэтому, если вы хотите иметь функцию, которая работает как с числами, так и с числами с плавающей запятой, вы можете использовать числовой вариант и сопоставлять его, в этом случае вы не захотите не нужно полагаться на полиморфизм на уровне модуля - код будет мономорфным c для типа варианта.
Но в таком случае вы можете не захотеть иметь функцию, принимающую и / или возвращающую вариант , Возможно, вы захотите предоставить отдельные реализации для int и float и явно вызвать соответствующую версию. Вы можете сделать это с помощью интерфейсов модулей и реализации модулей. Функторы полезны при реализации этого как сокращение для написания специализированных модулей вручную.
Вы задали тот же вопрос на https://discuss.ocaml.org/t/why-doesnt-a-specific-type-fulfill-a/5525/6. Там вам предоставили пример такого полиморфизма на уровне модуля с использованием ограничения совместного использования:
module type Printable = sig
type t
val say : t -> unit
end
module Int_print: Printable with type t := int = struct
let say i = Printf.printf "%d\n" i
end
module String_print: Printable with type t := string = struct
let say s = Printf.printf "%s\n" s
end
let () =
let open Int_print in
say 20 ;
let open String_print in
say "hello again"
Ocaml не имеет полиморфизма ad ho c, в результате чего компилятор выберет, какой из них таких предоставленных пользователем альтернатив следует применять в каждом конкретном случае (известном как «перегрузка функций» в C ++ и аналогичных языках): в ocaml кодировщик должен сам заявить об этом, как в примере выше.