2016-06-30 38 views
9

Mam typ unii kolorów, które chcę renderować dla użytkownika. Czy jest możliwe powtórzenie wszystkich wartości związków typu?Czy można powtórzyć typ związku w Wiąz?

type Color = Red | Blue | Green | Black 

colorToStirng color = 
    case color of 
     Red -> "red" 
     Blue -> "blue" 
     Green -> "green" 
     Black -> "black" 

colorList = 
    ul 
     [] 
     List.map colorListItem Color -- <- this is the missing puzzle 

colorListItem color = 
    li [class "color-" ++ (colorToString color) ] [ text (colorToString color) ] 

Odpowiedz

6

Niestety, nie. To niemożliwe.

Dla prostego typu ze skończoną liczbą wartości, takich jak typ Color, może się wydawać, że kompilator powinien mieć możliwość wygenerowania takiej listy. Jeśli chodzi o kompilator jest zaniepokojony choć, nie ma różnicy między swoim rodzaju i typu jak

type Thing = Thing String 

iteracyjne nad wszystkie wartości typu Thing będzie wtedy wymagają iteracji nad wszystkimi wartościami typu String.

+0

dzięki mimo to. Zamiast tego użyję prostej listy ciągów. –

3

Oczywiście, że możesz to zrobić. Po prostu nie automatycznie przez kompilator.

type Foo 
    = Bar 
    | Baz 
    | Wiz 

-- just write this for types 
-- you wish to use as enumerations 
enumFoo = 
    [ Bar 
    , Baz 
    , Wiz ] 

Działa to dobrze, ale oczywiście będzie ładniejszy i kompletności zaznaczone, jeśli wyliczenie jest zawsze obsługiwane przez kompilator.

colorList = 
ul 
    [] 
    List.map colorListItem enumFoo 
10

Problem z deklarowania funkcji, takich jak:

type Foo 
    = Bar 
    | Baz 

enumFoo = 
    [ Bar 
    , Baz ] 

jest to, że prawdopodobnie będziesz zapomnij dodać nowe teksty stałe do niego. Aby rozwiązać ten problem, grałem z tym (hacky, ale mniej hacky niż idei powyżej) idea:

enumFoo : List Foo 
enumFoo = 
    let 
    ignored thing = 
     case thing of 
      Bar -> () 
      Baz ->() 
      -- add new instances to the list below! 
in [ Bar, Baz ] 

ten sposób można przynajmniej się błąd dla funkcji i miejmy nadzieję, nie zapomnij dodać do listy.

+3

jest to w rzeczywistości sprytne obejście tego ograniczenia. Dzięki! – pietro909

+0

Gdzie 'thing' zostaje zdefiniowany? – JustGage

+1

"ignorowane" jest funkcją, więc "rzecz" jest argumentem. Funkcja nigdy nie jest wywoływana, ale nakazuje kompilatorowi sprawdzenie, czy wszystkie wyliczenia są wymienione w instrukcji case. Jest całkowicie oddzielony od poniższej tablicy - "[Bar, Baz]" - to podejście jest tylko sposobem na pojawienie się błędu kompilatora w pobliżu listy, z przypomnieniem programistom o dodaniu wpisu do tablicy. –