模式匹配嵌套的联合类型

Iva*_*tov 1 algebraic-data-types elm

我正在计算一个倒数/倒计时器.设置原始日期后,计时器将显示自 - 以来经过的时间,或者保持到原始日期为止.

type OriginDefined
    = Up Date
    | Down Date


type Origin
    = OriginDefined
    | OriginUndefined


type Model
    = Tick OriginDefined
    | Edit Origin
Run Code Online (Sandbox Code Playgroud)

因此,只有在定义了原始日期时,计时器才会打勾.编辑原点时,可能先前已定义或未定义.

现在我需要一个函数来返回defaultValue日期输入,当我们处于Edit模式时.

dateInputDefaultValue : Origin -> String
dateInputDefaultValue origin =
    case origin of
        OriginUndefined ->
            ""

        OriginDefined ->
            ...
Run Code Online (Sandbox Code Playgroud)

在这里,我努力将origin进一步构造为一个Up date或多个Down date.在case表达式的第二个分支中,编译器拒绝将其origin视为更具体而不仅仅是一个Origin.

这是一个Ellie https://ellie-app.com/3zKCcX87wa1/0

我应该如何处理这样的模型?我应该以不同的方式建模吗?

Cha*_*ert 6

你的类型编译,但你有两个不同的定义OriginDefined:一个是一个叫OriginDefined有两个构造函数的类型,UpDown.另一种是类型上的无参数构造函数Origin.

我的预感是你试图让OriginDefined构造函数Origin携带一个类型的值OriginDefined.为此,您必须OriginDefinedOriginDefined构造函数上定义类型的参数:

type Origin
    = OriginDefined OriginDefined
    | OriginUndefined
Run Code Online (Sandbox Code Playgroud)

现在你有一个与Elm Maybe类型同构的类型,所以也许它可以减少混淆和更惯用的删除OriginDefined类型并Origin用这个替换定义:

type Origin
    = Up Date
    | Down Date
Run Code Online (Sandbox Code Playgroud)

现在,您可以Maybe在以前使用过的地方使用已定义/未定义的命名法:

type Model
    = Tick (Maybe Origin)
    | Edit Origin
Run Code Online (Sandbox Code Playgroud)

模式匹配Maybe Origin可能如下所示:

dateInputDefaultValue : Maybe Origin -> String
dateInputDefaultValue origin =
    case origin of
        Nothing ->
            ""

        Just (Up date) -> 
            "…"

        Just (Down date) -> 
            "…"
Run Code Online (Sandbox Code Playgroud)