f = do
putStrLn "1"
putStrLn "2"
main = f
내가 이해하는 방식으로 f
은 (putStrLn "1")>>=(\_ -> (putStrLn "2"))
으로 줄어 듭니다. 람다 (모나드 제거 _)를 적용하는 동안 인쇄 작업이 완료 되었습니까? 누군가가 어떤 부분에서 평가되고 실행되는지 어떤 부분을 설명 할 수 있습니까?첫 번째 인쇄는 언제 haskell 코드에서 발생합니까?
f = do
putStrLn "1"
putStrLn "2"
main = f
내가 이해하는 방식으로 f
은 (putStrLn "1")>>=(\_ -> (putStrLn "2"))
으로 줄어 듭니다. 람다 (모나드 제거 _)를 적용하는 동안 인쇄 작업이 완료 되었습니까? 누군가가 어떤 부분에서 평가되고 실행되는지 어떤 부분을 설명 할 수 있습니까?첫 번째 인쇄는 언제 haskell 코드에서 발생합니까?
putStrLn
는 ()
느릅 후 폐기하고 단지 제 putStrLn
계산되어 얻어 번째 기능 에르고 때문에,이 계산을하고 그 IO
모나드에 ()
를 리턴 형 String -> IO()
이다.
순서는 다음과 같습니다
1 .- putStrLn "1"
2가 ()
결과로 얻을 수 있도록
3 .- \() -> putStrLn 2
4 .- putStrLn 2
정신 분열증은 그와 똑같지는 않지만, 당신이 생각할 수 있도록.
3 단계 후에 프로그램이 충돌했다면 화면에 "1"이 표시된다고 가정하십시오. – abhishek
@abhishek 수정. 'do {putStrLn "1"; undefined}''1'을 출력 한 다음 충돌합니다. – 4castle
@ 4castle 답장을 보내 주셔서 감사합니다. 여기서'f' 함수는 본체를 평가하고 main이 실행하는 main에 대한 모나드를 반환합니다. 그렇기 때문에 위의 코드에서 f가 절대적으로 안쪽 블록이나'>>'로 리턴하지 못하거나'>'이 결코 성공하지 못하므로 메인이 실행되지 않으므로 부작용이 발생하지 않습니다. AFAIU는 오직 부작용이 가능합니까? – abhishek
'IO'모나드는 특별히 부작용의 평가 순서를 보장하기 위해 설계되었습니다. 그러나 일반적으로 하스켈은 표현의 어느 부분이 먼저 평가되는지에 대한 보장을하지 않습니다. 유일한 보장은 가능한 한 게으르다는 것입니다. – 4castle