2017-02-09 5 views
1

나는 상태 모나드 here을 통해 갈거야 내가 구현하려고 해요 :상태 모나드를 구현할 때 데이터 생성자 오류가 발생 했습니까?

나는 다음과 같은 오류 받고 있어요 그러나
import Control.Monad.Reader 
import Control.Monad.Writer 
import Control.Monad.State 

type Stack = [Int] 

pop :: State Stack Int 
pop = State $ (x : xs) -> (x, xs) 

:

"Data constructor not in scope: 
    State :: ([t0] -> (t0, [t0])) -> State Stack Int 
Perhaps you meant one of these: 
    ‘StateT’ (imported from Control.Monad.State), 
    variable ‘state’ (imported from Control.Monad.State)" 

내가 여기 기본 뭔가를 놓치고 있습니까?

답변

4

없음이되지 않습니다. 이 튜토리얼은 조금 단순화하고있다. ( 또는 단지 구형 일 수도있다. 나는 그 중 두 가지 중 어느 것이 구식인지 알기에는 충분하지 않다.) Control.Monad.State은 모나드 변 환기StateT을 정의합니다. 또한 생성자 State가 아닌 것을 의미 않습니다, 튜토리얼 그러나 당신에게

type State s a = StateT s Identity a 

을 가르치고 무엇을 간단한 유형의 동의어 상당을 수출, 그것은 StateT (그리고 그것은 일반화 된 서명이 있습니다). 고맙게도, 지금은 그것에 대해 너무 걱정할 필요가 없습니다. State 건설에 대한

  • , 당신은 state 기능을 사용하고 서명 state :: (s -> (a,s)) -> State s a을 (실제로는보다 일반적인 서명이 - 당신이 오류 메시지에 건너)가 척 할 수 있습니다.
  • State을 디 구성하는 경우 패턴 일치 대신 runState :: State s a -> s -> (a,s)을 사용하십시오. 이 예에서

당신이 준 : 그 튜토리얼의 말씀이기 때문에

import Control.Monad.Reader 
import Control.Monad.Writer 
import Control.Monad.State 

type Stack = [Int] 

pop :: State Stack Int 
pop = state $ \(x : xs) -> (x, xs) 
+1

알렉 (Alec)에게 감사드립니다. 아주 오래되었습니다. 나는 노년기에 까다로워하지 않기 때문에 기쁘다. –

+0

[링크 된 자습서는 구식이 아니며 단순화되지 않습니다.] (http://hackage.haskell.org/package/mtl-1.0/docs/Control-Monad-State.html # t : State)'Identity '에 계층화 된 트랜스 포머가 해당 모나드를 직접 정의하는 것과 비교하여 런타임 비용이 들었을 것이라고 사람들이 걱정하고 많은 라이브러리 (mtl 포함)가 모나드와 트랜스포머를 모두 제공 할 때가있었습니다. 결국 코드 중복/유지 관리 부담에 대한 논쟁이이를위한 성과 논쟁에서 승리했습니다. –

2

State a에 대한 인터페이스가 함수를 래핑하는 데이터 생성자를 통해 이루어진다고 가정하는 이유는 무엇입니까? s -> (a, s)? 즉, 을 구현하는 간단한 방법인데 상태를 구현하지만 인터페이스를 제공하지 않았습니다. 대신 Control.Monad.State에 제공된 구문을 사용하십시오.

하나의 간단한 변화가 낮은 경우이 목적을 위해 설계 state 기능을 사용하는 단지입니다 : 대신 국가의 낮은 수준보기 작업의 대안으로

pop :: State Stack Int 
pop = state $ \(x : xs) -> (x, xs) 

을, 당신은으로 작업 할 수 있습니다 그 putget 기능을 통해 모나드 없습니다 :

pop :: State Stack Int 
pop = do 
    (x : xs) <- get 
    put xs 
    return x 
+2

그녀는 State' '에 해당 인터페이스를 가정 한 것입니다. : "'Control.Monad.State' 모듈은 상태 계산을 래핑하는 newtype을 제공합니다. 다음은 그것의 정의입니다 : newtype State a = State {runState :: s -> (a, s)}'". – Alec

+0

간단한 동의어를 사용하여 간단한 "상태"로 작업하는 "환영"을 내보내려면 패턴 동의어를 사용하는 것이 좋습니다. 안전한 강제 변환을 사용하면 런타임 비용이 0이되어야한다고 생각합니다. 이것은'Identity'에 적용된 대부분의 모나드 변압기로 확장 될 수 있습니다. – chi