2014-12-23 2 views
4

나는 Getter 및 Setter로 사용할 수있는 렌즈를 정의하려는 Haskell 코드의 레코드 유형을 사용합니다. 코드는 다음과 같습니다.설정 가능한 렌즈를 정의하는 방법

data Players = Players { _white :: Player 
         , _black :: Player 
         } deriving (Show, Eq) 
makeLenses ''Players 
_byColor :: Color -> Players -> Player 
_byColor White = _white 
_byColor Black = _black 
byColor col = to (_byColor col) 

Players은 흰색과 검정색 플레이어가있는 레코드입니다. 나는 렌즈 패션에서 플레이어를 얻을 수 있기를 원합니다. 예 :

players ^. byColor White . hp -- Access health-points of player 

그러나 색상으로 선택한 플레이어의 속성을 설정할 수도 있습니다. 예 : _players 필드와 함께 Game 레코드를 보유한 상태 모나드 내에서

No instance for (Contravariant Identity) 
    arising from a use of `byColor' 
Possible fix: 
    add an instance declaration for (Contravariant Identity) 

내가 잘못 뭐하는 거지 : 코드는 다음과 같은 오류 메시지와 함께 컴파일에 실패 그러나 byColor 내 최신 정의

let current = White 
players . byColor current . hp %= (-1) 

?

답변

3

to 조합 자만이 게터를 만듭니다. 전체 렌즈를 정의하지 않았습니다. 그러나 전체 렌즈를 정의하는 것은 매우 간단합니다. 전달 된 색상을 기준으로 올바른 렌즈를 반환하기 만하면됩니다.

byColor :: Color -> Lens' Players Player 
byColor White = white 
byColor Black = black 
+2

감사합니다. 생각보다 훨씬 쉽습니다. 죄송합니다, 이것이 바보 같은 질문 이었으면. 렌즈의 사용 설명서가 약간 어렵다는 것을 인정해야합니다. – Lemming

+2

@Lemming 나는 렌즈 라이브러리와 그 문서를 가지고 아직도 고심하고 있다고 말할 때 나를 신뢰한다. 적어도 문서가 있지만 다른 라이브러리보다 형식을 따르는 것이 확실히 어렵습니다. – bheklilr

관련 문제