You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elm 0.19.1中使用Json.Decode.andThen解码元组的类型不匹配问题

解决Elm 0.19.1解码器与Cmd元组的类型不匹配问题

问题本质是Elm的Json.Decode.andThen要求传入的函数返回纯Decoder a类型,但你试图在解码器中混合返回解码器和副作用命令(Cmd)——而Decoder设计为纯函数,无法携带副作用,因此必须拆分逻辑。

解决方案:拆分纯解码逻辑与Cmd生成

将解码逻辑和Cmd生成完全分离,先完成纯JSON解码得到Criterion值,再根据该值生成对应的命令列表。

1. 重构纯解码器

修改所有解码器,让它们仅返回纯Decoder Criterion,移除Cmd相关返回值:

import Json.Decode as JD exposing (Decoder, field)

type Criterion
    = Condition Condition
    | CriterionGroup ConditionGroup

-- 假设你已定义的Condition和ConditionGroup类型
type alias Condition = { ... }
type alias ConditionGroup = { ... }

criteriaDecoder : List Field -> List Operator -> Int -> Decoder Criterion
criteriaDecoder fields operators currentDepth =
    field "type" JD.string
        |> JD.andThen (criterionDecoder fields operators currentDepth)


criterionDecoder : List Field -> List Operator -> Int -> String -> Decoder Criterion
criterionDecoder fields operators currentDepth criterionType =
    case criterionType of
        "condition" ->
            JD.map Condition (conditionDecoder fields operators)

        "conditionGroup" ->
            JD.map CriterionGroup (groupDecoder fields operators currentDepth)

        _ ->
            JD.fail <| "Could not decode criterion for type: " ++ criterionType

-- 纯Condition解码器,仅处理JSON解码
conditionDecoder : List Field -> List Operator -> Decoder Condition
conditionDecoder fields operators =
    -- 替换为你原本的Condition解码逻辑(移除Cmd返回)
    JD.map2 Condition
        (field "field" JD.string)
        (field "operator" JD.string)

-- 纯ConditionGroup解码器,仅处理JSON解码
groupDecoder : List Field -> List Operator -> Int -> Decoder ConditionGroup
groupDecoder fields operators currentDepth =
    -- 替换为你原本的Group解码逻辑(移除Cmd返回)
    JD.map2 ConditionGroup
        (field "operator" JD.string)
        (field "criteria" (JD.list (criteriaDecoder fields operators (currentDepth + 1))))

2. 单独编写Cmd生成函数

根据解码后的Criterion值,生成对应的命令列表:

getCriteriaCmds : Criterion -> List (Cmd Msg)
getCriteriaCmds criterion =
    case criterion of
        Condition cond ->
            -- 生成与Condition对应的Cmd(替换为你的实际逻辑)
            getConditionCmds cond

        CriterionGroup group ->
            -- 生成Group对应的Cmd,并递归处理子Criteria的Cmd
            getGroupCmds group ++ List.concatMap getCriteriaCmds group.criteria

-- 示例:Condition对应的Cmd生成逻辑
getConditionCmds : Condition -> List (Cmd Msg)
getConditionCmds cond =
    [ Cmd.none ] -- 替换为实际需要的命令

-- 示例:ConditionGroup对应的Cmd生成逻辑
getGroupCmds : ConditionGroup -> List (Cmd Msg)
getGroupCmds group =
    [ Cmd.none ] -- 替换为实际需要的命令

3. 使用流程

解码JSON后,再调用Cmd生成函数得到最终结果:

decodeAndProcess : String -> Result String (Criterion, List (Cmd Msg))
decodeAndProcess jsonString =
    case JD.decodeString (criteriaDecoder fields operators 0) jsonString of
        Ok criterion ->
            Ok (criterion, getCriteriaCmds criterion)

        Err err ->
            Err (JD.errorToString err)

关键说明

Elm的Decoder是纯函数,仅负责将JSON转换为Elm数据,不能包含副作用逻辑(如Cmd)。将解码和Cmd生成分离,既符合Elm的纯函数设计原则,也解决了类型不匹配的问题。

内容的提问来源于stack exchange,提问作者TBatist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:56:09