Reputation: 83
I have this type
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
}
Inserting values
cat : Cat
cat =
{ head =
{ eyes = 2
, nose = 1
, mouth =
{ tongue = 1
, prey =
{ left = 1
, right = 1
}
}
}
}
I'm usually doing this to change the right side of the prey
let
newCat =
(Cat
(Head oldValue.eyes oldValue.nose
(Mouth
(Prey oldValue.left 1)
)
)
)
in
({model | cat = newCat }, Cmd.none)
And I hate hitting that, but I can not figure out how to do it the right way. When I try to do it right I can not return 'type cat'.
How to change the right prey in the right way?
Upvotes: 1
Views: 86
Reputation: 9885
You're already doing it the right way.
When you're dealing with nested records, you have to build them up, just like you're already doing.
Now, what you can do is abstract newCat
and turn it into a function of type Int -> Cat -> Cat
. Then, you'd be able to do ({model | cat = updateRightPrey 1 model.cat }, Cmd.none)
But honestly, you may want to reconsider your data model. Does Head
, Mouth
, and Prey
actually provide any value? What would you loose (and what would you have to gain) if you flatten your model like this:
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
Even if you change all those Int
type alias to types...
type Eyes = Eyes Int
... it would be a lot simpler than dealing with nested records:
let
cat = model.cat
in
({model | cat = { cat | right = 1 }, Cmd.none)
or...
let
cat = model.cat
in
({model | cat = { cat | right = Prey 1 }, Cmd.none)
Upvotes: 5