Любой способ избежать этой проблемы вывода типа? - PullRequest
2 голосов
/ 07 июня 2011

Если у меня есть функция, определенная как

let test = function
    | [] -> None
    | head::tail -> Some(head)

fsi позволит мне определить это, и компиляция скомпилирует это; но это упадет, если я когда-нибудь попытаюсь сделать test [].

Теперь я знаю причину: когда я даю ему пустой набор, он не может вывести тип, и поэтому универсальная функция дает сбой, но разве она не может сделать что-то более умное? (по типу «я не знаю тип 'a, но в этом случае я не использую 'a, поэтому я позволю это».)

В любом случае, можно ли как-нибудь избежать этой проблемы?

Ответы [ 2 ]

2 голосов
/ 07 июня 2011

Есть отличная статья об ограничении значений на MSDN и дополнительные заметки о хитрых аспектах Брайана, которые подробно объясняют эту проблему.

Когда вы пишете test [] результат имеет тип option<'a>, поэтому компилятору необходимо знать тип, который будет использоваться вместо 'a.Вы на самом деле не используете значения типа 'a, но компилятор должен скомпилировать код, который его использует.F # не позволяет работать с родовыми значениями (в общем), поэтому значение должно иметь конкретный тип.

Вы можете написать что-то вроде:

let foo () = test []

Thisявляется стандартной универсальной функцией типа unit -> option<'a>, так что это совершенно допустимая конструкция.Вы также можете использовать аннотации типов для явного указания типа результата:

(test []:option<obj>)
0 голосов
/ 07 июня 2011

Разумеется, последний случай [] сделает это?

...