내 safeMapM은 예외를 포착하지 않습니다.

발암 성

mapM실행시 예외가 발생하면 결과에서 요소를 제외하는 안전한 버전을 만들려고합니다 .

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

그래도 아무것도 잡지 못합니다. 간단한 테스트 케이스에서 :

safeMapM (\n -> return $ if n == 3 then error $ show n else n) [1,2,3,4,5]

다음과 같이 실패합니다.

*** Exception: 3
[1,2,"ghci>" 

왜 잡히지 않습니까? 잡을 evaluate만큼 충분히 평가하지 error않습니까? 서명이 변경 될 필요없이이 주위에 방법이 있나요 safeMapM :: (NFData a, NFData b) => (a -> IO b) -> [a] -> IO [b]및 사용은 deepseq?

아 말로이

evaluate x단지 평가 x에 그걸 얻기 위해 충분히 WHNF , 그리고 Just x심지어로 이미 WHNF에 x완전히 평가되지 않은 썽크. 그래서 당신은 evaluate (Just x)전혀 평가 x포함하지 않는 을 가지고 있습니다 !

f x함수 에 바인딩 하는 대신 다음과 같이로 래핑 하기 전에evaluate . Just 평가할 함수를 사용해야합니다 .x Just

returnEval :: Monad m => a -> IO (m a)
returnEval x = evaluate x >>= return . return

이 함수를 사용하면 다음과 같이 평가 줄을 다시 작성할 수 있습니다.

appliedResult <- onException (f x >>= returnEval) (return Nothing)

그 변화로 인해 표현의 결과 [1,2,**exception**]는 즉각적인 예외가됩니다. 다음 요점으로 넘어갑니다. onExceptionis not a "catch"block, it is more like finally like : "만약 문제가 발생하면이 코드를 실행하지만 두 경우 모두 첫 번째 표현식을 돌려주세요". catch대신 사용하도록 변경 하면 마침내 시작하려는 동작으로 끝납니다 [1,2,4,5]..

module SafeEval where
import Control.Exception

returnEval :: Monad m => a -> IO (m a)
returnEval x = evaluate x >>= return . return

safeMapM :: (a -> IO b) -> [a] -> IO [b]
safeMapM f []       = return []
safeMapM f (x : xs) = do
    restResult <- safeMapM f xs
    appliedResult <- catch (f x >>= returnEval) (\e -> (e :: SomeException) `seq` return Nothing)
    case appliedResult of
        Just x' -> return $ x' : restResult
        Nothing -> return restResult

그러나 John L이 주석에서 말했듯이 이것은 여전히 ​​최상위 수준의 예외 인 WHNF에 들어가는 데 필요한 예외 만 포착합니다. 중첩 된 전체 표현식에 대해 열심히 평가하려면 (아마도 그렇지 않을 수도 있음) deepseq와 같은 더 무딘 도구가 필요합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

내 safeMapM은 예외를 포착하지 않습니다.

분류에서Dev

오라클은 예외를 포착하지 않습니다

분류에서Dev

포착되지 않은 예외를 Google 분석에 보내기

분류에서Dev

Python : 내장되지 않은 예외를 포착하려면 가져와야합니까?

분류에서Dev

발생하지 않은 예외 포착

분류에서Dev

Swift 메일이 유효하지 않은 이메일에 대한 예외를 포착하지 않습니다.

분류에서Dev

AppCompActivity를 확장하면 포착되지 않은 예외가 발생합니다.

분류에서Dev

내 PDO에서 포착되지 않은 예외 'PDOException'오류

분류에서Dev

doOnError가 예외를 포착하지 않습니다

분류에서Dev

Jenkins cps groovy는 NoSuchMethodError 예외를 포착하지 않습니다.

분류에서Dev

Try-Catch는 예외를 포착하지 않습니다.

분류에서Dev

NodeJS : Promise는 throw 된 예외를 포착하지 않습니다.

분류에서Dev

포착되지 않은 예외를 수정하는 방법 : 헤더 서명

분류에서Dev

포착되지 않은 DOMException : 'HTMLCanvasElement'에서 'toDataURL'을 실행하지 못했습니다. 오염 된 캔버스를 내보낼 수 없습니다.

분류에서Dev

포착되지 않은 DOMException : 'HTMLCanvasElement'에서 'toDataURL'을 실행하지 못했습니다. 오염 된 캔버스를 내보낼 수 없습니다.

분류에서Dev

내 단위 테스트가 컨트롤러 작업 내에서 예외를 포착하지 못합니다.

분류에서Dev

Qt Creator로 컴파일 할 때 내 예외가 포착되지 않습니다.

분류에서Dev

HttpsURLConnection은 예외를 포착하지 않고 보안 경고 대화 상자를 표시합니다.

분류에서Dev

Android : 메인에서 치명적인 예외를 유발하는 포착되지 않은 예외

분류에서Dev

포착되지 않은 예외 처리기를 사용하여 예외에서 새 스레드 시작

분류에서Dev

텍스처를 추가하면 충돌이 발생합니다 ... (포착되지 않은 예외 'NSInvalidArgumentException')

분류에서Dev

내 코드에서 발생하지 않은 JavaScript 오류를 포착 할 수 있습니까?

분류에서Dev

중단을 유발하는 포착되지 않은 예외

분류에서Dev

왜`catch`가이 예외를 포착하지 않습니까?

분류에서Dev

Selenium PHP Webdriver-예외를 포착하지 않습니까?

분류에서Dev

try / catch를 사용하면 예외가 포착되지 않습니다.

분류에서Dev

왜 내`main ()`이 junit 테스트에서`timer`에 던져진 예외를 포착하지 못합니까?

분류에서Dev

WinCE에서 처리되지 않은 예외를 포착하는 방법은 무엇입니까?

분류에서Dev

포착되지 않은 예외를 확인하는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    내 safeMapM은 예외를 포착하지 않습니다.

  2. 2

    오라클은 예외를 포착하지 않습니다

  3. 3

    포착되지 않은 예외를 Google 분석에 보내기

  4. 4

    Python : 내장되지 않은 예외를 포착하려면 가져와야합니까?

  5. 5

    발생하지 않은 예외 포착

  6. 6

    Swift 메일이 유효하지 않은 이메일에 대한 예외를 포착하지 않습니다.

  7. 7

    AppCompActivity를 확장하면 포착되지 않은 예외가 발생합니다.

  8. 8

    내 PDO에서 포착되지 않은 예외 'PDOException'오류

  9. 9

    doOnError가 예외를 포착하지 않습니다

  10. 10

    Jenkins cps groovy는 NoSuchMethodError 예외를 포착하지 않습니다.

  11. 11

    Try-Catch는 예외를 포착하지 않습니다.

  12. 12

    NodeJS : Promise는 throw 된 예외를 포착하지 않습니다.

  13. 13

    포착되지 않은 예외를 수정하는 방법 : 헤더 서명

  14. 14

    포착되지 않은 DOMException : 'HTMLCanvasElement'에서 'toDataURL'을 실행하지 못했습니다. 오염 된 캔버스를 내보낼 수 없습니다.

  15. 15

    포착되지 않은 DOMException : 'HTMLCanvasElement'에서 'toDataURL'을 실행하지 못했습니다. 오염 된 캔버스를 내보낼 수 없습니다.

  16. 16

    내 단위 테스트가 컨트롤러 작업 내에서 예외를 포착하지 못합니다.

  17. 17

    Qt Creator로 컴파일 할 때 내 예외가 포착되지 않습니다.

  18. 18

    HttpsURLConnection은 예외를 포착하지 않고 보안 경고 대화 상자를 표시합니다.

  19. 19

    Android : 메인에서 치명적인 예외를 유발하는 포착되지 않은 예외

  20. 20

    포착되지 않은 예외 처리기를 사용하여 예외에서 새 스레드 시작

  21. 21

    텍스처를 추가하면 충돌이 발생합니다 ... (포착되지 않은 예외 'NSInvalidArgumentException')

  22. 22

    내 코드에서 발생하지 않은 JavaScript 오류를 포착 할 수 있습니까?

  23. 23

    중단을 유발하는 포착되지 않은 예외

  24. 24

    왜`catch`가이 예외를 포착하지 않습니까?

  25. 25

    Selenium PHP Webdriver-예외를 포착하지 않습니까?

  26. 26

    try / catch를 사용하면 예외가 포착되지 않습니다.

  27. 27

    왜 내`main ()`이 junit 테스트에서`timer`에 던져진 예외를 포착하지 못합니까?

  28. 28

    WinCE에서 처리되지 않은 예외를 포착하는 방법은 무엇입니까?

  29. 29

    포착되지 않은 예외를 확인하는 방법은 무엇입니까?

뜨겁다태그

보관