mapM
의 안전한 버전을 만들어 실행시 예외를 throw하는 경우 결과에서 요소를 제외하려고합니다.내 safeMapM은 예외를 catch하지 않습니다.
safeMapM :: (a -> IO b) -> [a] -> IO [b]
safeMapM f [] = return []
safeMapM f (x : xs) = do
restResult <- safeMapM f xs
appliedResult <- onException (f x >>= evaluate . Just) (return Nothing)
case appliedResult of
Just x' -> return $ x' : restResult
Nothing -> return restResult
비록 아무것도 잡는 데 실패합니다.
*** Exception: 3
[1,2,"ghci>"
왜 캐치되지 않는 :
safeMapM (\n -> return $ if n == 3 then error $ show n else n) [1,2,3,4,5]
가 실패 : 간단한 테스트 케이스에? evaluate
은 error
이 잡힐만큼 충분히 평가되지 않습니까? 서명을 safeMapM :: (NFData a, NFData b) => (a -> IO b) -> [a] -> IO [b]
으로 변경하고 deepseq
을 사용하지 않고이 문제를 해결할 방법이 있습니까?
'evaluate'은 WHNF 만 평가합니다. 이 경우,'evaluate'을 호출하기 바로 전에 추가 한'Just' 래퍼입니다. 'Just'를 제거하고 그에 따라 함수를 수정하면이 오류를 잡아야합니다. 그래도 'deepseq'를 사용하지 않으면 모든 것을 포착하지 못합니다. –
이것이 내가'error'와 다른 비동기 예외를 피하는 이유입니다. 그들은 잡기가 훨씬 더 어렵습니다. –