需要帮助建模调色板类型

Need help modeling a palette type

我正尝试按照 Model the problem 文章中的指南在 Elm 中创建 Palette 类型。我的第一个想法是:

type alias Palette = List Color

但这有缺点。调色板是颜色列表,但它也必须有两种颜色,一种用于背景,一种用于前景。

我的第二次尝试是记录类型:

type alias Palette = 
  { bg : Color
  , fg : List Color
  }

这样更好,但是如何确保 fg 字段是一个至少包含一个元素的列表?

关于如何从功能上思考的任何提示 make illegal states unrepresentable

谢谢!

如果我对你的问题的理解正确,那么你正在寻找一种数据类型来表示至少包含一个元素的列表。你可以用这样的东西定义你自己的这样的列表:

type NonEmptyList a = ListItem a (NonEmptyList a) | RootItem a

为了让生活更轻松,您可以定义一些辅助函数,以便您可以在普通 Elm 之间进行转换 List

toList : NonEmptyList a -> List a
toList list =
  case list of
    RootItem x -> [x]
    ListItem x rest -> x :: toList rest

fromList : List a -> Maybe (NonEmptyList a)
fromList list =
  case list of
    [] -> Nothing
    [x] -> Just (RootItem x)
    (x::xs) -> Maybe.map (ListItem x) <| fromList xs

然后您可以根据新的非空列表定义调色板。

type alias Palette = 
  { bg : Color
  , fg : NonEmptyList Color
  }

现在,编译器始终保证您的 fg 字段至少有一个值。