如何在榆树中查看自定义类型?
How to view custom type in elm?
这是数据模型,目标很简单,只需查看 HTML 中的类型 Gift
并且用户可以使用下拉列表更新 [=] 的字段 type_
13=]。但问题是如何从自定义类型构建下拉列表?
type Fruit
= Apple
| Banana
| Orange
type alias Gift =
{ quantity : int
type_ : Fruit
}
我试图在视图上添加一个 update/view
操作
如何将类型 Fruit
转换为字符串?有两种可能的解决方法:
构建字典,可能 Fruit
到 String
{Apple:"Apple",Banana,"Banana"}
我认为这行不通,因为 Dict
中的键必须是 Comparable
,但是如何在 custom type
中实现排序?有一个问题,但似乎还没有解决方案 (https://github.com/elm/compiler/issues/774)
使用Enum/makeEnum
模块
这将带来更多代码并且很容易破坏。
fruitTypeEnum = Enum.makeEnum [Apple, Banana, Orange ]
-- in view
(List.map (\x -> Enum.toString fruitTypeEnum x) [Apple,Banana,Orange])
这必须在三个地方维护 apple,banana,orange
列表(包括声明)
感谢您花时间阅读本文。感谢任何帮助:)
这里我只回答第一个问题(见我的评论)。不需要 Dict
,这是一个简单的函数:
fruitToString : Fruit -> String
fruitToString fruit =
case fruit of
Apple -> "Apple"
Banana -> "Banana"
Orange -> "Orange"
Elm 中没有内置方法来获取自定义类型的所有变体的列表(Elm 通常回避“魔术”元编程,而倾向于显式)。 ,使用 case
表达式是为自定义类型实现 toString
函数的一种非常简洁直接的方法。
该类型所有变体的列表必须与类型定义本身分开保存,但您应该创建一个列表,在这种情况下可能命名为 allFruit
,您可以在任何想要列出的地方使用他们都出去了。测试可以帮助您确保在询问新变体时不会遗漏任何内容。
一种更高级的技术是使用 code generation 从源代码自动创建列表。
要回答关于在 Dict 中使用其他类型作为键的另一个问题,可以使用 assoc-list
代替: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"
如您所见,Dict
您需要处理一个永远不会发生的情况。因此,外壳结构在这里是优选的。但是现在你知道如何创建一个以自定义类型作为键的字典了。
这是数据模型,目标很简单,只需查看 HTML 中的类型 Gift
并且用户可以使用下拉列表更新 [=] 的字段 type_
13=]。但问题是如何从自定义类型构建下拉列表?
type Fruit
= Apple
| Banana
| Orange
type alias Gift =
{ quantity : int
type_ : Fruit
}
我试图在视图上添加一个 update/view
操作
如何将类型 Fruit
转换为字符串?有两种可能的解决方法:
构建字典,可能
Fruit
到String
{Apple:"Apple",Banana,"Banana"}
我认为这行不通,因为
Dict
中的键必须是Comparable
,但是如何在custom type
中实现排序?有一个问题,但似乎还没有解决方案 (https://github.com/elm/compiler/issues/774)使用
Enum/makeEnum
模块 这将带来更多代码并且很容易破坏。fruitTypeEnum = Enum.makeEnum [Apple, Banana, Orange ] -- in view (List.map (\x -> Enum.toString fruitTypeEnum x) [Apple,Banana,Orange])
这必须在三个地方维护
apple,banana,orange
列表(包括声明)
感谢您花时间阅读本文。感谢任何帮助:)
这里我只回答第一个问题(见我的评论)。不需要 Dict
,这是一个简单的函数:
fruitToString : Fruit -> String
fruitToString fruit =
case fruit of
Apple -> "Apple"
Banana -> "Banana"
Orange -> "Orange"
Elm 中没有内置方法来获取自定义类型的所有变体的列表(Elm 通常回避“魔术”元编程,而倾向于显式)。 case
表达式是为自定义类型实现 toString
函数的一种非常简洁直接的方法。
该类型所有变体的列表必须与类型定义本身分开保存,但您应该创建一个列表,在这种情况下可能命名为 allFruit
,您可以在任何想要列出的地方使用他们都出去了。测试可以帮助您确保在询问新变体时不会遗漏任何内容。
一种更高级的技术是使用 code generation 从源代码自动创建列表。
要回答关于在 Dict 中使用其他类型作为键的另一个问题,可以使用 assoc-list
代替: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"
如您所见,Dict
您需要处理一个永远不会发生的情况。因此,外壳结构在这里是优选的。但是现在你知道如何创建一个以自定义类型作为键的字典了。