2012-01-31 5 views
3

이 문제를 해결하기 위해 이전에 관련 질문을 받았습니까? Implementation of State Monad 내 코드를 더 구체화하기 위해 하나의 증분 함수 만 사용하여 구현하려고했습니다.상태 모나드 예제 문제

module StateExample where 
import Control.Monad.State 

data GlobState = GlobState { c1 :: Int, c2:: Int, c3:: Int} deriving (Show) 

newGlobState:: GlobState 
newGlobState = GlobState { c1=0,c2=0,c3=0 } 

incr :: String-> State GlobState() 
incr x = do 
    modify(\g -> g {x =x g + 1}) 

main:: IO() 
main = do 
    let a1= flip execState newGlobState $ do 
     incr c1 
     incr c2 
     incr c1 
    print a 

하지만, 여기에 내가 오류 난이 오류를 제거 할 수있는 방법

`x' is not a (visible) constructor field name 

는 무엇입니까?

답변

8

당신은 하스켈의 약점을 뚫었습니다 : 기록은 최고 수준의 가치가 아닙니다! 실제로, 작성한대로 작성하는 것이 좋지만 불가능합니다. 그러나 다른 라이브러리를 사용하여 원하는 효과를 얻을 수 있습니다. 이 당신이 fclabels을 사용하는 경우가 모습입니다 :

{-# LANGUAGE TemplateHaskell, TypeOperators #-} 
module StateExample where 

import Control.Monad.State hiding (modify) 
import Data.Label (mkLabels) 
import Data.Label.Pure ((:->)) 
import Data.Label.PureM 

data GlobState = GlobState { _c1 :: Int , _c2 :: Int , _c3 :: Int } deriving Show 
$(mkLabels [''GlobState]) 

newGlobState:: GlobState 
newGlobState = GlobState { _c1 = 0, _c2 = 0, _c3 = 0 } 

incr :: (GlobState :-> Int) -> State GlobState() 
incr x = modify x (+1) 

main :: IO() 
main = do 
    let a = flip execState newGlobState $ do 
     incr c1 
     incr c2 
     incr c1 
    print a 

여기에 몇 가지 마법 부분이 있습니다. 동일한 레코드 이름을 가지지 만 앞에 밑줄이 붙은 GlobState을 정의합니다. 그런 다음 함수 mkLabelsTemplateHaskell을 사용하여 모든 필드에 대해 "렌즈"를 정의합니다. 레코드에 있습니다. 이 렌즈는 같은 이름이지만 밑줄은 없습니다. 인수 (GlobState :-> Int) ~ incr은 렌즈이며 함수는 Data.Label.PureM 에서 사용할 수 있습니다.이 함수는 상태 모나드에서 이와 같이 정의 된 레코드를 업데이트합니다. 충돌을 피하기 위해 modifyControl.Monad.State에서 숨 깁니다. getsputs로 당신은 상태 모나드와 사용 가능한 다른 기능에 대한 documentation for PureM 의 다른 기능을 볼 수

. 당신이 fclabels가 설치되지 않은,하지만 당신은 (당신이 하스켈 플랫폼을 설치하는 경우 당신이 얻을)가 cabal-install 패키지에서 cabal 실행 파일이있는 경우

, 당신은 단순히 실행하여 fclabels를 설치할 수 있습니다

cabal install fclabels 

하는 경우

cabal update 
+0

모듈 Data.Label.PureM이 라이브러리가없는 :이 먼저 데이터베이스를 업데이트해야합니다, 당신은 cabal 실행이 처음이다. 어떻게 설치합니까? –

+0

'fclabels'을 설치하는 방법에 대한 몇 가지 지침으로 제 답변을 업데이트했습니다. 그러면'Data.Label.PureM'에 Cabal이 제공됩니다. – danr

+1

렌즈 (또는 "라벨"또는 고객이 원하는 모든 것을 말하십시오) –