Elm:更新子类型中的值

Elm: Update value in sub types

我有这种类型

type alias Cat =
 { head : Head
 }

type alias Head =
  { eyes : Int
  , nose : Int
  , mouth : Mouth
  }

type alias Mouth =
  { tongue : Int
  , prey : Prey
  }

type alias Prey =
  { left : Int
  , right : Int 
  }

正在插入值

cat : Cat
cat = 
  { head = 
    { eyes = 2
    , nose = 1
    , mouth = 
      { tongue = 1
      , prey = 
        { left = 1
        , right = 1
        }
      }
    }
  }

我通常这样做是为了改变猎物的右侧

let  
  newCat = 
    (Cat 
      (Head oldValue.eyes oldValue.nose 
        (Mouth 
          (Prey oldValue.left 1)
        )
      )
    )
in
 ({model | cat = newCat }, Cmd.none)

而且我讨厌打那个,但我不知道如何以正确的方式做到这一点。当我尝试做对时,我不能 return 'type cat'.

如何以正确的方式改变正确的猎物?

你已经在做正确的事了。

当您处理嵌套记录时,您必须构建它们,就像您已经在做的那样。

现在,你能做的就是抽象newCat,然后把它变成Int -> Cat -> Cat类型的函数。然后,您就可以 ({model | cat = updateRightPrey 1 model.cat }, Cmd.none)

但老实说,您可能需要重新考虑您的数据模型。 HeadMouthPrey 实际上提供任何值吗?如果你像这样扁平化你的模型,你会失去什么(你会得到什么):

type alias Cat = 
  { eyes : Eyes
  , nose : Nose
  , tongue : Tongue
  , left : Prey
  , right : Prey 
  }

type alias Eyes = Int
type alias Nose = Int
type alias Tongue = Int
type alias Prey = Int

即使您将所有这些 Int 类型别名更改为类型...

type Eyes = Eyes Int

...这会比处理嵌套记录简单很多:

let
    cat = model.cat
in
({model | cat = { cat | right = 1 }, Cmd.none)

或...

let
    cat = model.cat
in
({model | cat = { cat | right = Prey 1 }, Cmd.none)