2016-06-30 35 views
9

Ho un tipo di unione di colori che voglio rendere all'utente. È possibile iterare su tutti i valori di unione di tipo?È possibile iterare su un tipo di unione in Elm?

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) ] 

risposta

6

Sfortunatamente, no. Non è possibile.

Per un tipo semplice con un numero finito di valori come il tipo Color, potrebbe sembrare che il compilatore debba essere in grado di generare tale elenco. Per quanto riguarda il compilatore è interessato, però, non v'è alcuna differenza tra il tipo e un tipo come

type Thing = Thing String 

per scorrere tutti i valori di tipo Thing avrebbe richiesto iterare su tutti i valori di tipo String.

+0

grazie comunque. Userò invece un semplice elenco di stringhe. –

3

Oh certo che puoi farlo. Semplicemente non automaticamente tramite il compilatore.

type Foo 
    = Bar 
    | Baz 
    | Wiz 

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

Questo funziona bene, ma ovviamente sarebbe più bello e esaustività controllato, se l'enumerazione è mai supportato dal compilatore.

colorList = 
ul 
    [] 
    List.map colorListItem enumFoo 
10

Il problema di dichiarare una funzione come:

type Foo 
    = Bar 
    | Baz 

enumFoo = 
    [ Bar 
    , Baz ] 

è che probabilmente si dimentica di aggiungere nuovi enumerazioni ad esso. Per risolvere questo problema, ho giocato con questo (hacky, ma meno hacky che l'idea di cui sopra) idea:

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

In questo modo si ottiene almeno un errore per la funzione e si spera non dimenticate di aggiungere alla lista.

+3

questo è in realtà una soluzione intelligente per una tale limitazione. Grazie! – pietro909

+0

Dove viene definita la cosa? – JustGage

+1

"ignorato" è una funzione, quindi "cosa" è l'argomento. La funzione non viene mai chiamata, ma indica al compilatore di verificare che tutte le enumerazioni siano elencate nell'istruzione case. È completamente separato dall'array sottostante - "[Bar, Baz]" - questo approccio è solo un modo per far apparire un errore del compilatore vicino all'elenco, con un promemoria per il programmatore di aggiungere una voce all'array. –