我想编写一个将自定义类型编码Decision a为JSON 的函数。该a标签可以是如Accept或Reject,我想我的函数调用取决于标签的类型等功能。
我曾尝试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)
如果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)