2017-02-02 11 views
1

이것이 조금 까다 롭습니다 만 왜 작동하지 않는지 궁금합니다!`seq`을 사용하고 haskell에서 인쇄하십시오.

module Main where 

sillyDebug :: Int -> Int -> Int 
sillyDebug x y = 
    (print x) `seq` (x + y) 

main :: IO() 
main = do 
    print (sillyDebug 1 2) 

이상적인 그것이 지연 평가 또는 하스켈 부작용과 관련되어

sillyDebug = (trace (show x) False) `seq` (x + y) 

같은 동안? https://hackhands.com/lazy-evaluation-works-haskell/

+1

http://stackoverflow.com/help/mcve를 참조하십시오. 대부분의 수입품은 부적합합니다. 'sillyIO'는 어디에도 정의되어 있지 않습니다. 'sillyDebug = (trace (show x) False) \'seq \'(x + y)'는 컴파일조차하지 않습니다. 그리고 직면 한 문제를 설명하십시오. 너는 무엇을 기대 했는가? 너는 무엇을 얻 느냐? – Jubobs

+0

죄송합니다, 그것은 내 잘못입니다 : 3 –

+1

이 문제는 * 표현식을 평가하고 * 모나드 동작을 실행하는 것의 차이점에 관한 것입니다. 그러나 나는 또한 'seq'에 대한 메모를 작성할 가치가 있다고 생각합니다. ''a'' seq''''는'a'의 평가를 정확하게 강제하지 않습니다. 썽크 (thunks) 사이의 종속성을 생성하므로 * b *가 평가되면 'a'도 평가됩니다. ''print (snd (x'seq' y, z))''절대'y'를 평가하지 않기 때문에''x''를 평가하지 않습니다. –

답변

4

일부를 평가하는 것만으로는 전혀 동작하지 않습니다. 당신은 IO과 같은 일종의 부작용이있을 수 있습니다. 실제로는 전혀 구현되지 않았을지라도 Haskell 일 수 있습니다. 이런 식으로 뭔가 :

Sequence :: IO a -> (a -> IO b) -> IO b 

이 생성자는 IO에 대한 >>=을 구현하는 데 사용됩니다 :이 이론 시각화의 IO 생성자의

data IO a where 
    PutStrLn :: String -> IO() 
    ReadFile :: FilePath -> IO String 
    ExitWith :: ExitCode -> IO a 
    ... 

하나는 이런 유형의 서명과 더불어, Sequence 생성자 것 유형.

GHC는 IO a -> amagicallyExecuteIO이라는 마법의 기능으로 각 동작이 실제로 해당 부작용을 수행하도록 조정합니다. (덧붙여이 함수는 때때로 unsafePerformIO으로 발음됩니다.) GHC는 프로그램의 main 함수의 결과와 GHCi로 작성된 표현식에 대해 magicallyExecuteIO을 암시 적으로 호출합니다.

그러나 magicallyExecuteIO을 사용하지 않고 구성 자 중 하나를 평가하면 PutStrLn과 같은 것은 아무 것도하지 않습니다.

ghci> Just (PutStrLn "hello!") 
Just (PutStrLn "hello!") :: Maybe (IO()) 

(. 나는 IO 조치를 실행 GHCi을 방지하기 위해 Just로 포장했습니다) 물론

, GHC의 실제 IO 유형 :이 구현에서, 그냥 다른 데이터 생성자처럼 작동합니다 이 방법으로 구현되지는 않지만 실제로는 구현 세부 사항입니다. IO a 값을 평가해도 부작용이 발생하지 않으므로 Maybe a 값을 평가하는 것 이상이 발생하지 않습니다. magicallyExecuteIO 만 가능합니다.