2014-01-18 2 views
2

단 하나의 대답 만 원할 때 fold {l, r}을 끝내려면 어떻게해야합니까?하스켈에서 단 하나의 답을 원한다.

내가 부울 목록 b1, b2, b3, ...을 가지고 있다고 가정하고 또는 모두 함께 사용하고 싶습니다. 첫 번째 진정한 가치에 멈추게하려면 어떻게해야합니까?

+0

jozefg의 답변보다 짧습니다. GHCi에서'$ try True'를 시도하십시오! – leftaroundabout

+0

@leftaround에 대해서, 그것은 단지 Prelude에서 정의 된'or = foldr (||) False' 때문입니다. GHC는 실제로 특수 또는 빌드 최적화를 가능하게하는 컨텍스트를 기반으로 어떤 이유로 재귀 적으로 정의합니다. – dfeuer

답변

14

이미 있습니다! 예를 들어의이 목록

foo :: [Bool] 
foo = [False, False, False, True] ++ repeat False 
을 만들어 보자 repeat 그냥 무한 목록을 만들고,

우리는 GHCi

*Main> foldr (||) False foo 
    True 

이를로드하는 경우 "하지만,하지만 어떻게?" 당신은 궁금해 할 것입니다. 하스켈은 게으르며, foldr입니다. 당신이 구현에서 보면,이 평가되지 않습니다 당신이 그것을 평가할 때, f 경우 그 오른쪽이 필요하지 않습니다이

foldr f a [b, c, d, e ... z] == (b `f` (c `f` (... (z `f` a)..))) 

공지 사항 같은 것을 만들어 것을 알 수 있습니다 우리는 할 수 그것이 무한하더라도 목록의 나머지 부분은 모두 무시하십시오. 하스켈과 같은 게으른 언어에서도 가능합니다. 필요할 때만 평가하기 때문입니다. ||의 경우

은이 왼쪽에 해당하는 경우, 우리는 목록을 평가 중지

True || _ = True 
False || a = a 

로 정의되어 있기 때문이다. 무료 단락!

참고 : foldl은 목록의 모든 요소를 ​​감동하므로이 멋진 속성을 공유하지 않습니다. 이것은 엄지의 좋은 법칙으로 이어지며, 단락/비 엄격 성을 원하면 보통 foldr이 적합합니다. 그렇지 않으면 foldl'이 더 빠를 것입니다.

관련 문제