2012-11-22 2 views
0

Monads와 Haskell이 처음인데, 이것을 사용할 때 값을 반환하는 방법을 이해하려고합니다. 내 코드는 다음과 같이 보입니다 :상태 모나드로 값 반환하기

foo :: A -> B 
foo a = do b <- fooC a (C 0) 
      -- want to return just (B "b") 

fooC :: A -> C -> State MyState B 
fooC a c = return (B "b") 

내가 snd (snd b)를 사용하여 시도,하지만 분명히 State MyState B는 튜플 아닌가요? 원하는 값 (B "b")을 반환하려면 어떻게해야합니까?

편집 : 계정에 다니엘의 조언을 촬영, 재 작성은 다음과 같습니다 여전히 컴파일 오류가 발생

data MyState = MyState String 
data C = C Int 
foo :: String -> String 
-- want to return just "b" 
foo a = evalState (fooC a) (C 0) 

fooC :: String -> Int -> State MyState String 
fooC a c = return "b" 

을 :

Couldn't match expected type `State s0 String' 
      with actual type `Int -> State MyState String' 
In the return type of a call of `fooC' 
Probable cause: `fooC' is applied to too few arguments 
In the first argument of `evalState', namely `(fooC a)' 
In the expression: evalState (fooC a) (C 0) 

편집 2 : 고정! 다음과 같이 최종 버전은 같습니다 당신이 필요로하는 무엇

import Control.Monad.State 
data MyState = MyState String 
data C = C Int 
foo :: String -> String 
-- want to return just (B "b") 
foo a = evalState (fooC a (C 0)) (MyState "whatever") 

fooC :: String -> C -> State MyState String 
fooC a c = return "b" 

main = print(foo("test")) 
-- prints "b" 

답변

6

foo a = evalState (fooC a (C 0)) (MyState "whatever") 

당신은 함수를 얻을 수를 풀다의 State MyState B 행동 fooC a (C 0)를 구성하고, 초기 상태로 그 기능을 적용 할 수 있습니다. 이 예제에서는 상태가 사용되지 않으므로 MyState "whatever" 대신 undefined을 사용할 수도 있지만 일반적으로 의미있는 초기 상태를 제공해야합니다.

State MyState B

는 함수

MyState -> (B, MyState) 

동형하지만 그 기능에 싸여 튜플 아닌 newtype되도록 결과를 액세스하기 위해, (상세 모나드 변압기 라이브러리 패키지 및 버전에 따라 다름) 함수가 초기 상태에 적용되면 래핑 해제 함수가 필요합니다. State 들어 께 쌍 복귀 기능을 제공

runState :: State s r -> (s -> (r,s)) 

최종 상태가 폐기되도록하면 fst 함께 구성하는 기능을 제공

evalState :: State s r -> (s -> r) 

execState :: State s r -> (s -> s) 
을 거기 snd으로 함수를 구성하는

이므로 최종 상태 만 반환됩니다.

+0

작동하지 않는 것 같습니다. 내 게시물의 편집을 참조하십시오. –

+0

죄송합니다. 구문 분석에 실패했습니다. 업데이트 됨. –

+0

일했습니다! 다니엘 감사합니다! –