2017-10-24 2 views
4

Parallel and Concurrent Programming in Haskell에서 bracket 기능을 보면 : 예외가 발생할 경우는 이해`bracket` 기능

bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c 
bracket before after during = do 
    a <- before 
    c <- during a `onException` after a 
    after a 
    return c 

는 왜 after 기능은 한 번만 호출됩니까? 즉, 나는 예외의 경우에 두번 명백한 실행 after a에 혼란스러워합니다.

λ: >data MyException = MyException deriving Show 
λ: >instance Exception MyException 

λ: >let e = return MyException :: IO MyException 

λ: >bracket e (const $ putStrLn "clean up!") return 
clean up! 
MyException 
+1

내 생각에'onException'은'after a'를 실행할 것입니다. 그러나 예외를 "re-raises"하여 함수의 나머지 부분을 막지 만 이것을 검증하지는 않았습니다. 파이썬과 마찬가지로'try-exception' 블록을 가지고 있지만'except : print (foo); 일부 명령을 한 후에 예외를 재발행하라. –

답변

6

the docs for bracket에서 :

당신이 자원을 취득 그것으로 어떤 일을 할 때 한번, 이해

그러나이 코드는, after a 만 호출되는 것을 보여줍니다 리소스를 해제하면 bracket을 사용하는 것이 좋습니다. 왜냐하면 bracket이 계산 중에 예외가 발생하는 경우 리소스를 해제하는 데 필요한 예외 처리기를 설치하기 때문입니다. 예외가 발생하면 bracket은 릴리스를 수행 한 후 예외를 다시 발생시킵니다.

그리고 onException : finally 추천

하지만은 계산에 의해 발생 예외가 발생했을 경우, 최종 동작을 수행한다. 그래서 after a 처음 호출이 실행 during a에서 발생 예외가 발생했을 경우

후 예외는 제 after a 스킵, 슬로우 다시되고; 예외가 없으면 초만 실행됩니다. 샘플 코드에서, 당신은 예외를 반환있어

참고가-할 수는 throw 바람직 throwIO :: Exception e => e -> IO a를 사용해야 던져을 던지는되지 .