기능적 언어의 게터와 세터


9

함수형 프로그래밍의 신조 중 하나는 순수 함수를 사용하는 것입니다. 순수한 기능은 부작용이 없으며 참조가 투명합니다.

Getter 는 참조 용으로 투명하지 않습니다. Getter 호출간에 Setter를 호출하면 매개 변수가없는 경우에도 Getter의 리턴 값이 변경됩니다 (일반적으로 매개 변수 없음).

세터 는 부작용을 일으 킵니다 -세터를 호출하면 일반적으로 반환 값이 아닌 값을 조작합니다 (사실 전통적으로 세터는 아무것도 반환하지 않습니다)

스칼라에서 우리는 두 가지 패러다임 (함수 및 객체 지향)을 함께 메쉬하고 있다는 사실을 받아들이고 Java와 같은 언어에서와 마찬가지로 getter / setter를 사용합니다.

Haskell과 같은 언어 (유창하지는 않지만 "순수한"기능 언어를 더 잘 알고 있음)에서 Getter가 참조 적으로 투명하고 Setter가되도록 객체의 속성을 모델링하는 방법이 궁금합니다. 부작용은 없습니까?

해결책은 setter가 호출 된 오브젝트의 사본을 setter의 리턴 값으로 전달하고이 사본에 특성 값의 변경 사항이 포함되어 있습니까?


8
게터와 세터는 일반적으로 암시 적이지만 개체를 ​​매개 변수로 사용하므로 게터 참조 적으로 투명합니다.

읽고있는 속성이 변경 불가능한 경우에만 @delnan.
dan_waterworth

3
@dan_waterworth : "referentially transparent"의 "같은"을 객체 동일성으로 읽는 경우에만 해당됩니다. 기본 속성이 다른 사실은 다른 인수를 사용하여 호출합니다 (대부분의 평등 정의에 부합). 이것은 setter를 호출하는 다른 스레드를 무시하고 getter 호출과 getter 마무리 사이에서 마무리하는 것이지만 어쨌든 더 심각한 문제가 발생합니다.

답변:


7

바로 그거죠. 케이스 클래스 방법 copy또는 렌즈의 일반적인 개념을 참조하십시오 .

특히 상태를 변경해야하는 경우 State 모나드를 사용합니다. 렌즈를 통해 상태 모나드를 변경할 수 있으므로 "상태"에서 정보를 추출하고 쉽게 변경할 수 있습니다.

"상태"와 같은 깊은 구조에서 발생하고 변경하는 일반적인 문제에 대한 이 질문 도 참조하십시오 . 더 깊이 들어가고 싶다면 렌즈와 지퍼 모두에 대한 좋은 링크가 있습니다.


질문 Daniel : copy ()가 Case 클래스와 관련이있는 특별한 이유가 있습니까? 이것은 구체적으로 Case 클래스의 요구 (잘못 된 단어이지만 다른 것을 생각할 수는 없음)에 특정하게 보이지는 않지만 모든 클래스에 적합한 기능이 더 많이 보입니다. 케이스가 아닌 클래스에 copy ()가 필요한 경우 어떻게합니까? 해당 기능을 얻는 데 사용할 수있는 특성이 있습니까?
ThaDon

1
@ThaDon 케이스 클래스는 생성자 매개 변수로 정의되어야합니다. 동등성, 해시 코드 및 추출기는이 가정을 기반으로하며 복사 방법도 마찬가지입니다. 사례가 아닌 클래스에서는 생성자 매개 변수가 클래스를 복사하는 데 필요한 전부인지 추측 할 수 있습니다. 그러나 자신 만의 복사 방법을 쉽게 작성할 수 있습니다.
Daniel C. Sobral

11

Haskell에서 객체는 (보통) 불변이므로 getter (레코드 구문을 사용할 때 얻는) 또는 getter처럼 작동하는 함수 참조가 투명합니다. 그런 다음 개체에 값을 "설정"하지 않습니다. 이전 개체와 비슷하지만 필드 중 하나에 다른 값을 가진 개체를 만드는 경우 . 이것은 또한 순수한 기능입니다.


1
"개체는 (보통) 불변이다"때가 아닌가?
SARA

-1

"게터와 세터는 일반적으로 암시 적 임에도 불구하고 개체를 매개 변수로 사용하므로 게터는 참조 적으로 투명합니다. – delnan"

참조 적으로 투명한 것은 함수가 항상 동일한 입력에 대해 동일한 출력을 리턴 함을 의미합니다. 따라서 setter가 오브젝트 속성을 변경 한 경우 동일한 출력을 리턴하지 않습니다. :)


그러나 객체가 setter에 의해 변경된 경우 getter에 대한 입력 (즉, 암시 적 자체 인수)이 변경되었습니다.
Stephen C. Steel

1
오브젝트가 힙에서 이동하지 않으면 오브젝트 참조 값 / 포인터가 변경되지 않았습니다.
케이시 호손

5
그렇습니다. 그러나 논리적으로 암시 적 입력은 포인터 값이 아닌 객체 자체입니다.
Stephen C. Steel

"세터가 오브젝트 속성을 변경 한 경우 동일한 출력을 리턴하지 않습니다": 기능적인 측면에서 첫 번째 오브젝트를 삭제하고 새 오브젝트를 작성했습니다. 성능상의 이유로 (오래된 객체에서 새로운 객체로의 참조 복사 및 업데이트는 피함) 기존 객체가 포함 된 동일한 메모리 영역에 새 객체를 저장합니다.
조르지오
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.