тип «option‹unit-›unit› и равенство» с использованием F#

Рассмотрим следующий код:

let fnOption = Some (fun () -> ())
fnOption = None

Это дает следующую ошибку:

init.fsx(2,1): ошибка FS0001: тип «(unit -> unit)» не поддерживает ограничение «равенство», поскольку это тип функции

Это почему? Я что-то проглядел?


person Oldrich Svec    schedule 15.07.2011    source источник
comment
Функции являются значениями первого класса в FP, но они являются особыми типами значений в том смысле, что они используются для создания других значений на основе параметров, которые вы им передаете, поэтому нет смысла сравнивать 2 функции и, как следствие, есть оператор равенства не определен для функций   -  person Ankur    schedule 16.07.2011


Ответы (2)


Если вы действительно хотели проверить на равенство (а не присвоить значение), то вы можете использовать Option.isNone fnOption. Если вы действительно хотите назначить, посмотрите ответ kvb.

person Ramon Snir    schedule 15.07.2011
comment
Это правда. Я не заметил эту функцию. Значит ли это, что F# пытается добиться структурного равенства? Но опять же сразу можно было увидеть, что Some XXX ‹› None и даже не пришлось проверять, что внутри. - person Oldrich Svec; 15.07.2011
comment
Ошибка возникает во время компиляции, а не во время выполнения. Компилятор F# пытается скомпилировать код, но терпит неудачу, так как The type '(unit -> unit)' does not support the 'equality' constraint. В динамических языках (без проверки типов перед компиляцией) это могло бы работать со структурным равенством. - person Ramon Snir; 15.07.2011
comment
Теперь я понимаю. Спасибо за разъяснение - person Oldrich Svec; 15.07.2011

Непонятно, что вы пытаетесь сделать. В настоящее время вторая строка представляет собой проверку на равенство, а не назначение. Если вы намеревались присвоить новое значение fnOption, вам нужно сделать его изменяемым:

let mutable fnOption = Some(fun () -> ())
fnOption <- None

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

person kvb    schedule 15.07.2011
comment
Функции несопоставимы, а опции есть, верно? Я умею: let a = Some 4; a = None - person Oldrich Svec; 15.07.2011
comment
может ли он использовать Some id вместо Some (fun() -> ())? - person Alex; 16.07.2011
comment
@Alex - нет, значения типов функций несопоставимы, так же как и параметры, содержащие функции (независимо от того, каковы фактические значения). Даже (None : (unit -> unit) option) = None не будет компилироваться, потому что компилятор не смотрит внутрь значения опции; определение возможности сравнения значений производится исключительно на основании их типов. - person kvb; 16.07.2011