2012-03-22 3 views
10

원칙적으로 haskell의 형식 시스템은 순수한 함수에서 불순한 함수 (즉, f :: a -> IO b)를 호출하는 것을 금지한다고 생각했지만 오늘은 return으로 호출하여 실현했습니다. 예에서 :순수 함수 내에서 IO 작업의 의미는 무엇입니까?

h :: Maybe() 
h = do 
    return $ putStrLn "???" 
    return() 

이제, 어쩌면에 h 작품 모나드,하지만 그럼에도 불구하고 순수한 기능입니다. 실제로 컴파일 및 실행하면 실제적으로 I/O를 수행하지 않고도 예상대로 Just()을 반환합니다. 나는 haskell의 게으름이 함께 물건을 넣는다고 생각한다. (즉, putStrLn의 반환 값은 사용되지 않는다. 그리고 그 값 생성자가 숨겨져 있고 패턴 매치가 불가능하므로이 코드가 합법적 인 이유는 무엇인가? 이것을 허락하는 다른 이유가 있습니까?

보너스와 관련된 질문 : 일반적으로 다른 사람들의 모나드 행위를 모두 금지 할 수 있습니까? 방법?

답변

19

입출력 동작은 다른 것과 마찬가지로 최상위 값입니다. 이것이 하스켈의 IO를 매우 표현력있게 만들어줌으로써 고차원 제어 구조 (예 : mapM_)를 처음부터 구축 할 수있게 해줍니다. 게으름은 여기에 관련이 없습니다. 실제로 동작이 이 아니므로 조치를 취하십시오. 값 Just (putStrLn "???")을 만든 다음 던져 버리는 것입니다.

putStrLn "???"기존은 화면에 선을 인쇄하지 않습니다. 그 자체로 putStrLn "???"은 행을 화면에 인쇄하도록하기 위해 수행 할 수있는 IO의 설명입니다. 유일한 실행은 main을 실행하는 것입니다.이 작업은 다른 IO 작업 또는 GHCi에 입력 한 작업으로 구성됩니다. 자세한 내용은 introduction to IO을 참조하십시오.

사실, 당신은 IO 내부의 동작을 저글링하고 싶을 수도 있습니다. Maybe; 문자열이 유효한지 검사하고 유효한 경우 문자열에서 파생 된 일부 정보를 출력하기위한 IO 작업을 반환하는 함수 String -> Maybe (IO())을 상상해보십시오. 이는 하스켈의 일급 IO 작업으로 인해 가능합니다.

하지만 모나드는 당신이 그 능력을 부여하지 않으면 다른 모나드의 행동을 실행할 능력이 없습니다.

실제로 h = putStrLn "???" `seq` return()putStrLn "???"의 평가를 강제 실행하더라도 IO가 수행되지 않습니다.

+0

어떻게하면 모나드에 포함 된 값과 패턴 매치 할 수있는 가능성을 부여하여 다른 모나드로부터 액션을 실행할 수 있습니까? –

+3

하나의 모나드를 다른 모나드로 변환하는 메소드를 작성하거나 실행합니다. 'Control.Monad.ST.stToIO'는'ST' 계산을'IO' 계산으로 변환합니다. –

+0

맑음. 둘 다 감사합니다! –

4

하자! 당신이 h을 평가할 때

h = do return (putStrLn "???"); return() 
-- rewrite (do foo; bar) as (foo >> do bar) 
h = return (putStrLn "???") >> do return() 
-- redundant do 
h = return (putStrLn "???") >> return() 
-- return for Maybe = Just 
h = Just (putStrLn "???") >> Just() 
-- replace (foo >> bar) with its definition, (foo >>= (\_ -> bar)) 
h = Just (putStrLn "???") >>= (\_ -> Just()) 

이제 어떻게됩니까? * 음, 어쩌면에 대한

(Just x) >>= f = f x 
Nothing >>= f = Nothing 

그래서 우리는 패턴 첫 번째 경우와 일치

f x 
-- x = (putStrLn "???"), f = (\_ -> Just()) 
(\_ -> Just()) (putStrLn "???") 
-- apply the argument and ignore it 
Just() 

우리가 수행 할 수 없었 방법 공지 사항 이 표현을 평가하기 위해 putStrLn "???".

* n.b. 어떤 점에서 "desugaring"이 멈추고 "평가"가 시작되는지는 다소 불분명하다.컴파일러의 인라이닝 결정에 따라 다릅니다. 순수 계산은 컴파일 타임에 완전히 평가 될 수 있습니다.

+1

desugaring 주셔서 감사합니다. 초보자에게 매우 유용합니다. 나는 많은 사람들이 설탕을 가지고 시작하는 이유를 이해하지 못합니다. 먼저 저녁을 먹고 사막을 먹습니다. – masterxilo

관련 문제