[haskell] 레코드의 단일 필드를 할당하고 나머지 필드를 복사하는 간단한 방법은 무엇입니까?

다음 레코드 ADT가 있다고 가정 해 보겠습니다.

data Foo = Bar { a :: Integer, b :: String, c :: String }

필드 중 하나를 제외한 모든 필드가 인수로 전달 된 값과 동일한 값을 갖는 레코드 (같은 유형의)를 반환하는 함수를 원합니다.

walkDuck x = Bar { a = a x, b = b x, c = lemonadeStand (a x) (b x) }

위의 내용은 작동하지만 필드가 더 많은 레코드 (예 10:)의 경우 이러한 기능을 만들려면 많은 입력이 필요하므로 불필요하다고 생각합니다.

덜 지루한 방법이 있습니까?



답변

예, 레코드 필드를 업데이트하는 좋은 방법이 있습니다. GHCi에서는 할 수 있습니다.

> data Foo = Foo { a :: Int, b :: Int, c :: String }  -- define a Foo
> let foo = Foo { a = 1, b = 2, c = "Hello" }         -- create a Foo
> let updateFoo x = x { c = "Goodbye" }               -- function to update Foos
> updateFoo foo                                       -- update the Foo
Foo {a = 1, b = 2, c = "Goodbye" }


답변

이것은 렌즈에 좋은 일입니다 .

data Foo = Foo { a :: Int, b :: Int , c :: String }

test = Foo 1 2 "Hello"

그때:

setL c "Goodbye" test

‘test’의 필드 ‘c’를 문자열로 업데이트합니다.


답변

보조 기능을 정의하거나 렌즈를 사용할 필요가 없습니다. Standard Haskell에는 이미 필요한 것이 있습니다. Don Stewart의 예를 들어 보겠습니다.

data Foo = Foo { a :: Int, b :: Int , c :: String }

test = Foo 1 2 "Hello"

그런 다음 test { c = "Goodbye" }업데이트 된 레코드를 받으라고 말하면 됩니다.


답변