F #: Как мне сопоставить шаблон со значением типа? - PullRequest
9 голосов
/ 28 апреля 2011

У меня есть функция, которая принимает общий параметр, и внутри него мне нужно выполнить одну из двух функций в зависимости от типа параметра.

member this.Load<'T> _path =
    let hhType = typeof<HooHah>
    match typeof<'T> with
        | hhType -> this.LoadLikeCrazy<'T> _path
        | _ -> this.LoadWithPizzaz<'T> _path

.... где LoadLikeCrazy и LoadWithPizzaz оба возвращают 'T.

VS сообщает мне, что случайный символ никогда не будет выполнен, так как я, очевидно, получаю тип универсального во время компиляции, а не фактический тип во время выполнения Как мне это сделать?

Ответы [ 3 ]

13 голосов
/ 28 апреля 2011

В вашем коде первое правило сопоставления с образцом не сравнивает typeof <'T> с hhType.Вместо этого будет введено новое значение с именем hhType.Вот почему вы получили предупреждение.Я бы лучше изменил код следующим образом.

member this.Load<'T> _path =        
    match typeof<'T> with        
    | x when x = typeof<HooHah>  -> this.LoadLikeCrazy<'T> _path        
    | _ -> this.LoadWithPizzaz<'T> _path
2 голосов
/ 28 апреля 2011

Является ли _path экземпляром 'T? Если это так, решение Talljoe будет работать, в противном случае вам придется сделать что-то вроде:

member this.Load<'T> _path =
    if typeof<'T> = typeof<HooHah> then this.LoadLikeCrazy<'T> _path
    else this.LoadWithPizzaz<'T> _path

Причина ошибки заключается в том, что hhType в вашем выражении match скрывает предыдущее объявление hhType. Таким образом, он просто фиксирует значение выражения соответствия в новой привязке. Это соответствует всему, поэтому ваше условие подстановки никогда не будет изменено.

0 голосов
/ 28 апреля 2011

То, что упомянул nyinyithann, верно. Я написал следующий код в F #

let Hello name = 
let n = "Sample"
match name with
| n -> 1
| _ -> 0

Получил то же предупреждение. Использовал отражатель, чтобы увидеть, какой код генерируется, и нашел следующий код (декомпилированный в C #)

public static int Hello<a>(a name)
{
  a local = name;
  a name = local;
  return 1;
}

Не уверен, почему компилятор сделал это :(. Кто-нибудь может описать это поведение?

...