Непонятная ошибка при использовании F # Active Pattern - PullRequest
3 голосов
/ 02 октября 2010

Почему этот компилятор:

let (|T|F|) b = 
    let f (o:int) : obj = null
    if b then T else F(f)

пока не получится:

let (|T|F|) b = 
    let f (o:obj) : obj = null
    if b then T else F(f)

Разница между этими двумя примерами заключается в том, что аргумент 'o' приводится к типу int (компилируется) или к obj (не компилируется)

1 Ответ

8 голосов
/ 02 октября 2010

Это неудачный угловой вывод типа. Это будет работать:

let (|T|F|) b : Choice<unit,obj -> obj> =   
  let f (o:obj) : obj = null
  if b then T else F(f)

В вашем исходном коде, несмотря на вашу аннотацию (o:obj), F # делает вывод, что o может фактически иметь любой тип 'a, что приводит к универсальному активному шаблону типа bool -> Choice<unit,'a -> obj>. Поскольку 'a является переменной свободного типа, F # не примет это активное определение шаблона. Вы можете увидеть похожую проблему, если сделаете что-то вроде:

let (|T|F|) b =   
  if b then T else F []

Опять же, решение будет заключаться в том, чтобы мономорфизировать определение:

let (|T|F|) b : Choice<unit,int list>  =   
  if b then T else F []
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...