두 가지 버전의 문제가 생겼습니다. 비슷한 효율성을 가져야한다고 생각합니다. 그렇지만 그렇지 않습니다. 나는 그것이 하스켈의 게으른 평가 행동 때문이라고 생각한다. 그것은 다음과 같은 예를 들어 어떻게 작동하는지 사람이 꽤 작동 nqueens2 동안 크기 8하스켈의 게으른 평가 동작을 이해하는 데 도움이 필요합니다
의 보드를 평가하기 위해 nqueens1 8 8 8 8 nqueens2를 호출하여
nqueens1 n 1 = [[i] | i <- [1..n]]
nqueens1 n k = [ i:q | i <- [1..n], q <- (nqueens1 n (k - 1)), isSafe i q k]
isSafe i q n = isSafeHelper i (zip q [(n-1),(n-2)..1])
where isSafeHelper i [] = True
isSafeHelper i (x:xs) = (i /= fst x) && abs(i - (fst x)) /= abs(n - (snd x)) &&
isSafeHelper i xs
nqueens2 n 1 = [[i] | i <- [1..n]]
nqueens2 n k = [ i:q | i <- [1..n], q <- boards, isSafe i q k]
where boards = nqueens2 n (k-1)
당신이 그들을 평가할 수 설명해 주시겠습니까 효율적으로 nqueens1 성능 문제가 있습니다. 재귀 호출 (nqueens n (k-1))이 여러 번 평가되기 때문입니다. 하스켈의 게으른 평가에 대한 나의 이해에서 보면, 그렇게해서는 안된다.
이 동작을 이해하는 데 도움을주십시오. 사전에
감사합니다.
"게으른 평가를"늦게 물건을 평가에 관한 것입니다 -하지 평가 뭔가 많은 시간을 피하는. –
@DanielWagner 실제로 게으른 평가와 call-by-name의 차이점은 call-by-name을 사용하여 여러 번 평가되는 특정 표현식은 lazy evaluation을 사용하여 한 번만 평가된다는 것입니다. 그것은 여기의 문제와 관련이 없습니다. – sepp2k
@ sepp2k 네가 맞아, 나는 "게으른 평가"대신 "전화 걸기"라고 말하거나 "여러 번 평가하는 것을 피하는"대신 "메모 작성"이라고 말하면서보다 정확 해졌어야했다. –