Функции, которые передаются в качестве аргументов другим функциям (например, display
), сами по себе не могут быть полиморфными в F #.Они могут использовать параметр общего типа ('a
и т. Д.), Но фактический тип для этого параметра указывается при вызове основной функции (NotWorking
в вашем случае).Это означает, что вы можете вызывать display
только с одним действительным типом, используемым для переменной типа 'a
в теле NotWorking
.
. В качестве временного решения вы можете использовать интерфейс с универсальным методом:
type Displayer =
abstract Display : (obj -> unit) -> 'T list -> unit
let NotWorking (display:Displayer) =
display.Display (printfn "%O") [1;2;3]
display.Display (printfn "%O") ["a";"b";"c"]
Метод Display
интерфейса сам по себе является универсальным методом, поэтому вы можете вызывать этот метод несколько раз с аргументами разных типов (int
в первом случае и string
во втором).
Однако я не нашел это ограничение при написании нормального кода на F # очень часто, поэтому, возможно, есть более простое решение для вашей проблемы (возможно, использование неуниверсального IEnumerable
или чего-то простогокак это - или obj list
, как в ответе Джона).Если вы дадите более подробную информацию о вашем фактическом коде, это было бы полезно.
Некоторая справка , на тот случай, если вас интересуют теоретические детали, но на самом деле все это не то, что могло быиграть важную роль в повседневном программировании на F #.В любом случае -
Это возможно в других языках, таких как Haskell, и механизм, который позволяет это, называется универсальные типы .Когда у вас есть полиморфная функция в F #, это, по сути, означает, что область видимости переменных типа является всей функцией, поэтому ('a -> unit) -> unit
можно рассматривать как forall 'a . ('a -> unit) -> unit
.
Когда вы вызываете функцию, вам нужно указать, что такое 'a
и что нельзя изменить (т. Е. Вы не можете использовать функцию 'a -> unit
, которую вы получаете в качестве аргумента с двумя различными типами для 'a
как только 'a
исправлено).
Используя универсальные типы, вы можете написать forall
самостоятельно, так что вы можете сказать, что тип:
(forall 'a . 'a -> unit) -> unit
.Теперь универсальный параметр 'a
связан только с функцией, которую вы получите в качестве аргумента.Тип функции, заданной в качестве аргумента, теперь сам по себе является универсальной функцией, и поэтому вы можете вызывать ее с разными типами, обозначающими 'a
.
PS: ограничение значений - это другая проблема - по сути это означает, что F #не может сделать вещи, которые не являются синтаксическими функциями, универсальными, но в вашем примере вы пишете синтаксические функции, так что это не проблема здесь.