"Elm에서는 중첩 레코드 업데이트를 수행할 수 없습니다."
주어진:
type alias Model =
{ person : Person
}
type alias Person =
{ firstName : String
, lastName : String
}
...
update
함수를 작성할 때 시도해야 할 자연스러운 현상은 다음과 같습니다.update msg model =
case msg of
UpdatedFirstName firstName ->
{ model | person =
{ model.person |
firstName = firstName
}
}
컴파일러는 그것을 좋아하지 않을 것입니다. 당신도 마찬가지입니다. 이것은 방법이 아닙니다.
자연스러운 다음 단계는 항상 다음과 같습니다.
update msg model =
case msg of
UpdatedFirstName firstName ->
let
currentPerson = model.person
updatedPerson =
{ currentPerson | firstName = firstName }
in
{ model | person = updatedPerson }
하지만 우리가 더 좋습니다. 우리는 더 잘할 수 있습니다. 날 따라와
Elm은 정말, 정말 간단한 언어입니다. 언어의 모든 것은 내부적으로 일관된 의미 체계를 따릅니다. 나는 무언가가 내가 예상한 대로 작동하지 않을 때 내 기대가 틀렸다는 것을 의미합니다. 즉, 언어의 정신적 모델이 불완전하거나 잘못되었음을 의미합니다. (주의: "기대하는 대로 작동하는"시스템을 설계한다고 주장하는 사람들 - 어떻게 그런 주장을 할 수 있습니까? 이러한 일이 예상대로 정확히 작동하는 사람들의 하위 집합은 누구입니까? 그들은 최적화하기에 적합한 사람들의 하위 집합입니까? 1 )
몇 주 전에 느릅나무 전구 중 하나가 소켓에 깔끔하게 떨어졌고 나는 느릅나무의 지침 중 하나를 발견했습니다.
기능은 왼쪽으로 이동합니다. 매개변수는 오른쪽으로 이동합니다.
(네, 알아요
|>
; 거울이 어떻게 작동하는지 아세요?)이것은 충분히 명백해 보이지만, 모든 것이 즉시 명백하지는 않은 흥미로운 함의를 갖고 있습니다.
a
가 있고 b
로 바꾸고 싶다면 a
왼쪽에 함수를 넣어 b
로 바꾸면 됩니다. 함수를 호출하고 다음과 같이 호출합니다.aToB : a -> b
aToB valueA
하지만 한 번만 사용해야 하는 경우에는 어떻게 해야 합니까? 왜 그냥 람다를 작성하지 않습니까?
(\a -> b) valueA
하지만 당신은 이미 알고 있었고, 나는 아직 방에 있는 코끼리에게 말을 걸지 않았습니다. 값을 취하고 레코드를 반환하는 람다를 작성할 수 있다는 것도 알고 있었을 것입니다.
왜 나는 이것을 전에 보지 못했습니까?
update msg model =
case msg of
UpdatedFirstName firstName ->
{ model |
person =
(\p ->
{ p | firstName = firstName }
) model.person
}
"와, 존. 깔끔한 파티 트릭. 하지만 -"
네가 옳아. 이것은 은색 총알이 아닙니다. 때때로, 당신은 당신을 위해 이것을 하는 함수를 작성해야 합니다. 어떤 사람들은 빌더 패턴2을 사용하여 다음과 같이 깔끔한 작업을 할 수 있습니다.
update msg model =
case msg of
UpdatedFirstName firstName ->
{ model | person =
model.person
|> withUpdatedFirstName firstName
}
withUpdatedFirstName : String -> Person -> Person
withUpdatedFirstName firstName =
(\person -> { person | firstName = firstName } )
그러나
update
함수에서 중첩 레코드를 한 번만 업데이트하면 되므로 빌더 패턴에 항상 도달할 필요는 없습니다.게다가, 그것은 이 작은 에세이의 원래 내용도 아닙니다.
Elm 초급 또는 중급 개발자로서 "이를 수행하는 더 나은 방법이 있어야 함"을 느낀다면 아마도 있을 것입니다. 찾으러 가서 찾을 때까지 찾는 것을 멈추지 마십시오.
그게 다야. 잘자, 조심해.
업데이트/편집: 지난 밤에 Elm Slack3에 이것을 게시했으며 Jeroen Engels는 친절하게 이 글을 읽고 약간의 정오표를 자세히 설명하고 몇 가지 개선 사항을 제안했습니다. 여기에서 그의 말을 인용하겠습니다.
I think one of the options I end up going for in the end, is to have a separate function to update Person, in a separate Person module where the Person type is opaque. That's I think usually where you get the most benefits and it feels least cumbersome (if you already have the opaque type), and I think it would be valuable to mention it here.
불투명한 유형은 이 게시물의 범위를 벗어납니다4, 그러나Charlie Koster does a great job of explaining them, here, for anyone interested.
DHH를 사랑하거나 싫어하거나, 이 문서는 여전히 관련이 있습니다: https://rubyonrails.org/doctrine -
Ctrl+F "surprise"
관련 섹션으로 이동합니다. ↩https://sporto.github.io/elm-patterns/basic/builder-pattern.html ↩
http://elmlang.herokuapp.com/ ↩
나는 그것을 설명할 자격이 없다고 느끼기 때문에, 그리고 나의 schtick은 "초보자를 그들 자신으로부터 구하는 것"과 "내 죄를 속죄하는 것"이기 때문입니다. 아직 배울 것이 많습니다. ↩
Reference
이 문제에 관하여("Elm에서는 중첩 레코드 업데이트를 수행할 수 없습니다."), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jmpavlick/you-cant-do-nested-record-updates-in-elm-hjh텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)