从集合中更新记录字段

4

最近我在学习 Elm,但是遇到了一个简单的问题,我想要更新记录字段。我的代码如下:

-- MODEL


initialModel : Model
initialModel =
    { selectedLanguage = "german"
    , allCards = Card.cards
    }


type alias Msg =
    { description : String
    , data : String
    , id : String
    }


更新功能
update : Msg -> Model -> Model
update msg model =
    case List.head (model.allCards) of
        Just card ->
            { card | fliped = True }
        Nothing -> model


但是我看到了这个:
Something is off with the 1st branch of this `case` expression:

50|             { card | fliped = True }
                ^^^^^^^^^^^^^^^^^^^^^^^^
The 1st branch is a record of type:

    { back : String, fliped : Bool, front : String, id : String }

But the type annotation on `update` says it should be:

    Model

Hint: Seems like a record field typo. Maybe back should be allCards?

Hint: Can more type annotations be added? Type annotations always help me give
more specific messages, and I think they could help a lot in this case!
Detected errors in 1 module.

我认为根据我的类型定义,应该从update函数中始终返回一个模型,但是我不知道如何做到。 请问有什么建议吗?

1个回答

4
你还需要更新modelallCards字段。 如果前者返回的是一个卡片列表而不仅仅是单个卡片,则可以将卡片更新嵌套在模型更新中:
update : Msg -> Model -> Model
update msg model =
    { model
    | allCards =
        case model.allCards of
            card :: rest ->
                { card | fliped = True } :: rest

            [] ->
                []
    }

如果你喜欢,可以将新的allCards绑定到一个名称上:

update : Msg -> Model -> Model
update msg model =
    let
        newAllCards =
            case model.allCards of
                card :: rest ->
                    { card | fliped = True } :: rest

                [] ->
                    []
    in
    { model | allCards = newAllCards }

我在这里直接对列表进行模式匹配,而不是使用List.head,因为它还给我剩余的列表,我不必处理中间值Maybe(或者实际上两个,因为List.tail也返回Maybe)。如果allCards包含至少一张卡,那么card::rest分支就会命中,因此唯一剩下的情况是[],这很容易处理。
另外,flipped用两个p拼写;)

谢谢@glennsl,很有道理。如果我想根据ID而不是第一个元素来获取某些内容,我可以使用相同的方法吗? - Édipo Féderle
1
你无法使用模式来通过ID查找某个东西,因为那不是数据的“形状”之一。相反,你可以使用List.map和一个检查ID并在匹配时返回其他内容的函数,否则什么也不做。例如:List.map (\item -> if item.id == 34 then { item | flipped = False } else item) items - glennsl
或者使用来自 https://package.elm-lang.org/packages/elm-community/list-extra/6.1.0/List-Extra 的 updateIf,它正是这样做的。 - Gelineau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接