在自定义类型的标签上是否可以有“ case ... of”语句?

Eri*_*Eng 5 elm

我想编写一个将自定义类型编码Decision a为JSON 的函数。该a标签可以是如AcceptReject,我想我的函数调用取决于标签的类型等功能。

我曾尝试case ... of根据Decision类型和标记来编写该语句,但无法获得两种工作方式。

这是我的类型:

type Decision a
    = Decision Metadata a


type Accepted
    = Accepted AcceptDetails


type Rejected
    = Rejected RejectDetails


type alias Metadata =
    { time : Time.Posix }


type alias AcceptDetails =
    { comment : String }


type alias RejectDetails =
    { reasonCode : Int }
Run Code Online (Sandbox Code Playgroud)

现在,我想写一个可以做出两种决定的编码器。类似于以下内容:

encoder : Decision a -> Json.Encode.Value
encoder decision =
    case decision of
        Decision _ (Accepted _) ->
            acceptedEncoder decision

        Decision _ (Rejected _) ->
            rejectedEncoder decision
Run Code Online (Sandbox Code Playgroud)

这不起作用,但希望它传达了我想要的内容-将编码任务路由到适当的功能。

这可能吗?还是我必须以其他方式解决它,例如根据决策类型直接调用正确的编码器?

我认为a可能存在任何问题,但是,天真的,也可以通过添加_案例来处理。

编译器给出错误信息:

The first pattern is trying to match `Decision` values of type:

    Decision Accepted

But the expression between `case` and `of` is:

    Decision a
Run Code Online (Sandbox Code Playgroud)

Cha*_*ert 4

如果ainDecision a只能是 an ApprovedorRejected类型,那么将两个构造函数合并为一个类型似乎是合适的。

type DecisionResult
    = Accepted AcceptDetails
    | Rejected RejectDetails
Run Code Online (Sandbox Code Playgroud)

这将消除对类型参数的需要Decision

type Decision
    = Decision Metadata DecisionResult
Run Code Online (Sandbox Code Playgroud)

然后,您的encoder函数可以将决策元数据和批准/拒绝的详细信息路由到更具体的编码器:

encoder : Decision -> Json.Encode.Value
encoder (Decision meta result) =
    case result of
        Accepted details ->
            acceptedEncoder meta details

        Rejected details ->
            rejectedEncoder meta details

acceptedEncoder : Metadata -> AcceptDetails -> Json.Encode.Value
acceptedEncoder meta details =
    ...

rejectedEncoder : Metadata -> RejectDetails -> Json.Encode.Value
rejectedEncoder meta details =
    ...
Run Code Online (Sandbox Code Playgroud)