2012-04-09 3 views
18

너무 오랜 시간이 걸리는 순수 계산을 "kill"할 수 있습니까? 시도했지만순수 함수 시간 초과

import System.Timeout 

fact 0 = 1 
fact n = n * (fact $ n - 1) 

main = do maybeNum <- timeout (10^7) $ (return . fact) 99999999 
      print maybeNum 

그러나 이것은 작동하지 않습니다. (return . fact) 99999999getLine과 같은 "실제"IO 기능으로 바꾸면 예상대로 작동합니다.

+0

'사실'IO 작업 ('사실 0 = 반환 1, 사실 n = (n *) \'fmap \'(사실 $ n - 1)')이되면 '시간 초과'는 예상했다. –

+0

@MatveyAksenov : 나는이 함수가 실제 IO 동작이기 때문에 그렇게 생각하지 않지만, 그 재귀가'fmap'을 통해'IO' 모나드로 옮겨 졌기 때문에 그렇게 생각합니다. – leftaroundabout

+2

임의 및 잠재적으로 악의적 인 코드를 시간 초과해야하는 경우 정말로 간단한 비 할당 루프 (예 : 'let x = x in x' 그리고'let x() = x() in x()'. –

답변

20

점은

return (fact 999999999) 

즉시 반환하고 타임 아웃을 트리거하지 않습니다. 나중에 평가 될 썽크를 반환합니다. (제한 시간이 스택 오버 플로우 전에 발생 있도록 충분히 큰 스택을 제공하는 경우)이 타임 아웃을 트리거한다

main = do maybeNum <- timeout (10^7) $ return $! fact 99999999 
      print maybeNum 

당신이 반환 값의 평가를 강제하는 경우

.