2011-04-28 12 views
9

Mam funkcję, która pobiera ogólny parametr, a wewnątrz niego potrzebuję wykonać jedną z dwóch funkcji w zależności od typu parametru.F #: Jak wzorzec pasuje do wartości typu?

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

.... gdzie LoadLikeCrazy i LoadWithPizzaz zwracają wartość 'T.

VS informuje mnie, że przypadek wieloznaczny nigdy nie zostanie wykonany, ponieważ najwyraźniej otrzymuję typ generyczny w czasie kompilacji, a nie rzeczywisty typ w czasie wykonywania. Jak mam to zrobić?

Odpowiedz

13

W kodzie pierwsza reguła dopasowania wzorca nie porównuje typu < "T> z typem hhType. Zamiast tego wprowadzi nową wartość o nazwie hhType. To jest powód, dla którego otrzymałeś ostrzeżenie. Wolę zmodyfikować kod w ten sposób.

member this.Load<'T> _path =   
    match typeof<'T> with   
    | x when x = typeof<HooHah> -> this.LoadLikeCrazy<'T> _path   
    | _ -> this.LoadWithPizzaz<'T> _path 
+0

słodki, dzięki nyinyithann! – MiloDC

2

Czy _path jest instancją 'T? Jeśli tak, to rozwiązanie Talljoe będzie działać, inaczej będziesz musiał zrobić coś takiego:

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

Przyczyną błędu jest hhType ciągu swojej wypowiedzi match jest shadowing uprzedniej deklaracji hhType. Jest to po prostu przechwytywanie wartości wyrażenia dopasowania do nowego powiązania. Wszystko to pasuje, dlatego twój warunek wieloznaczny nigdy nie zostanie trafiony.

0

To, co nynnyithann wspomniał, jest poprawne. Napisałem poniższy kod w F #

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

Otrzymałem to samo ostrzeżenie. Używane reflektor, aby zobaczyć, co kod jest generować i znaleźć poniższy kod (dekompilowana w C#)

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

Nie wiem, dlaczego kompilator to zrobił :(. Czy ktoś może opisać ten problem?

+0

Co Zachowanie, jakiego oczekujesz od swojego kodu? Wzorzec dopasowania nad nazwą, tj. (nazwa dopasowania z), to dwie alternatywy, w pierwszej regule tworzysz nowe powiązanie zmiennej, zwane także "nazwą", a następnie zwracasz 0. Ponieważ nie określa żadnego wzorca lub kiedy strażnik zawsze będzie pasował do pierwszej reguły, co oznacza, że ​​druga zasada jest zbędna, co dokładnie próbujesz osiągnąć? – Robert

+0

Zaktualizowałem kod ... w rzeczywistości pierwszy wzorzec był: n -> 1 ... po wydaniu go wydaje się, że "nazwy" (zmienne) - w tym przypadku "n" - zdefiniowane wewnątrz dopasowania mają swój własny zakres i nie mają nic wspólnego z wiązaniami wykonanymi przed blokiem dopasowania – Ankur

+1

może uzyskać zachowanie, którego szukasz za pomocą atrybutu Literał, Chris Smith ma więcej szczegółów: http://blogs.msdn.com/b/chrsmith/archive/2008/10/03/f-zen-the-literal- attribute.aspx – Robert

Powiązane problemy