연습으로 저는 하스켈에서 명령 행 RPN 계산기를 작성하고 있습니다. 아이디어는 입력 (숫자 또는 연산자)을 요구하고 새로운 스택을 출력합니다. 내 계획은 상태 모나드에 숫자 목록을 저장하고 해당 목록에 대해 계산을 수행하는 것입니다. 예 :IO를 상태 계산과 혼합하기
> 4
[4]
> 3
[3,2]
> 5
[5,3,2]
> +
[8, 2]
등등.
각 항목에 입력 & 출력이있는 상태 모나드에서 목록을 작성하는 것으로부터 시작하고 있습니다. 나는 이미 동일한 기능의 IO & 상태의 조합으로 인해 막혔다. 내 문제는 첫 번째 숫자를 입력 한 후에 프롬프트를 계속 유지하려면 입력 내용을 재귀 적으로 처리해야한다는 것입니다.
module Main where
import Control.Monad.State
addEntry :: Int -> State [Int] Int
addEntry entry = do
entries <- get
put (entry : entries)
return entry
mainLoop :: [Int] -> IO()
mainLoop entries = do
entry <- readLn
newEntries <- execState (addEntry entry) entries
print newEntries
mainLoop newEntries
main :: IO()
main = do
print $ mainLoop []
여기 나는 현재 받고 있어요 컴파일러 오류입니다 : 여기
지금까지 내 코드입니다src/[email protected]:28-14:42 Couldn't match type [Int] with ‘IO [Int]’
Expected type: State (IO [Int]) Int
Actual type: State [Int] Int …
src/[email protected]:44-14:51 Couldn't match expected type ‘IO [Int]’ with actual type [Int] …
난하도록이 기능을 구성하는 방법에 대한 팁 IO & 상태를 결합하지 않습니까?
'StateT [Int] Identity Int' ('State [Int] Int'와 동일) 대신 'StateT [Int] IO Int'를 사용하셨습니까? 그런 다음'liftIO'를 사용하여 IO 동작을 'StateT [Int] IO' 모나드로 옮기고 같은 동작 블록에서 상태 저장 연산과 IO 동작을 수행 할 수 있습니다. – bheklilr
파일 상단에'{- # LANGUAGE FlexibleContexts # -}'를 추가하면'addEntry'의 타입 시그니처를'MonadState [Int] m => Int ->로 변경하면 컴파일 할 수 있습니다. m Int'로 변경 한 다음'execState'를'execStateT'로 변경하십시오.'print $ mainLoop []'와 컴파일러 오류가 있지만, 인쇄 자체를 수행하고 아무 것도 반환하지 않기 때문에'mainLoop []'이어야합니다 . [Like this] (https://gist.github.com/7331ab8d54ba17d82cae) – bheklilr
실제 응용 프로그램에서 실제로 IO 랩핑 값을 사용자의 상태로 전달하는 것이 일반적입니까? 실제 상태 계산이 어떤 이유로 IO에 의존하지 않는다면, 그것은 나에게 상당히 더럽다고 느낍니다. –