如何在榆树中查看自定义类型?

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 转换为字符串?有两种可能的解决方法:

  1. 构建字典,可能 FruitString

     {Apple:"Apple",Banana,"Banana"}
    

    我认为这行不通,因为 Dict 中的键必须是 Comparable,但是如何在 custom type 中实现排序?有一个问题,但似乎还没有解决方案 (https://github.com/elm/compiler/issues/774)

  2. 使用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 您需要处理一个永远不会发生的情况。因此,外壳结构在这里是优选的。但是现在你知道如何创建一个以自定义类型作为键的字典了。