Reputation: 1884
here is data model , the goal is easy, just to view the type Gift
in the HTML and user can use a dropdown list to update field type_
of Gift
. But the question is how to build dropdown list from a custom type ?
type Fruit
= Apple
| Banana
| Orange
type alias Gift =
{ quantity : int
type_ : Fruit
}
I tried to add a update/view
operation on view
how to convert the type Fruit
to String ? There are two possible workarounds:
Building a dict, which mays Fruit
to String
{Apple:"Apple",Banana,"Banana"}
I don't think this will work since key in Dict
needs to be Comparable
,but how to implement ordering in custom type
? there was an issue but there seems no solution yet (https://github.com/elm/compiler/issues/774)
Using Enum/makeEnum
module
this will bring more code and easily can break.
fruitTypeEnum = Enum.makeEnum [Apple, Banana, Orange ]
-- in view
(List.map (\x -> Enum.toString fruitTypeEnum x) [Apple,Banana,Orange])
this has to maintain apple,banana,orange
list in three places ( including the declaration )
Thank you for your time reading this .Appreciate any help:)
Upvotes: 2
Views: 319
Reputation: 96
To answer the other question about using other types as keys in Dict, there is the possibility to use assoc-list
instead: https://package.elm-lang.org/packages/pzp1997/assoc-list/latest/
import AssocList as Dict exposing (Dict)
type Fruit
= Apple
| Banana
| Orange
fruitStrings : Dict Fruit String
fruitStrings =
Dict.fromList
[ ( Apple, "Apple" )
, ( Banana, "Banana" )
, ( Orange, "Orange" )
]
fruitToString : Fruit -> String
fruitToString fruit =
Dict.get fruit fruitStrings |> Maybe.withDefault "Not a fruit"
As you can see, with a Dict
you need to handle a case that could never happen. The case construction is therefore preferable here. But now you know how to create a dictionary with custom types as keys.
Upvotes: 0
Reputation: 156055
There is no built in way in Elm to get a list of all of the variants of a custom type (Elm generally shies away from "magic" metaprogramming in favor of explicitness). As glennsl answered, using a case
expression is a very clean and straightforward way to implement a toString
function for a custom type.
The list of all variants of that type must be keep separately from the type definition itself, but you should create one list, maybe named allFruit
in this case, that you can use anywhere you want to list them all out. Tests can help you ensure you don't miss anything when asking a new variant.
One more advanced technique is using code generation to create a list from the source code automatically.
Upvotes: 4
Reputation: 29146
I'll only answer the first question here (see my comment). No Dict
needed, it's a simple function:
fruitToString : Fruit -> String
fruitToString fruit =
case fruit of
Apple -> "Apple"
Banana -> "Banana"
Orange -> "Orange"
Upvotes: 3