2011-09-11 2 views
0

제가 (http://www.haskell.org/haskellwiki/Euler_problems/11_to_20#Problem_11)에 주어진 Euler.11 용액을 복사하지만 인덱싱 에러 실패 "(.! 배열) : 정의되지 않은 배열 요소". 물론 첫 번째로 더 나은 오류 메시지 (!)를 원합니다. 아마도 실패한 색인을 제공하는 것일 수도 있지만, 오류가있는 색인을 제공하는 것만으로는 오류를 디버그하려고했습니다.디버깅리스트 통합

데이터가 올바르게 입력되고 인쇄 된 데이터에 올바른 경계와 데이터가 표시됩니다.

그래서 몇 가지 추적 메시지를 결과 표현식과 이해력 본문에 추가했습니다. 나는 최종 표현식으로부터 많은 추적 결과를 얻었지만, 신체 계산 결과는 얻지 못했다. 왜?

prods :: Array (Int, Int) Int -> [Int] 
-- trace ("xs: " ++ show xs) (product xs) 
prods a = [trace ("xs: " ++ show xs) (product xs) | i <- range $ bounds a, 
         s <- senses, 
         let trace1 = check "i: " i, 
         let is = take 4 $ iterate s i, 
         let trace2 = check "is: " is, 
         all (inArray a) is, 
         let xs = map (a!) is] 

-- Doit 
-- euler = print . maximum . prods . input =<< getContents 
euler eData = maximum . prods $ input eData 

-- Debugging tracecheck :: String -> a -> a 
check msg v | trace (msg ++ (show v)) True = v 

답변

2

먼저 오류 메시지에 실패 인덱스를 포함 시키려면 배열 인덱스에 Show 제약 조건을 추가해야하며 이는 바람직하지 않을 수 있습니다.

두 번째로, 로마가 말했듯이, 게으른 평가 때문에 메시지가 인쇄되지 않습니다. Bang-patterns (let !trace = check "i: " i)은이를 우회하는 가장 편리한 방법 일 수 있지만 목록 작업 내에서 어떻게 작동하는지 정확히 알지 못합니다.

다음은 배열이 잘못 작성되었다는 것을 알려주며 (일부 요소는 정의되지 않은 채로 남았 음),이를 사용하는 함수가 아닌 함수를 구성하는 함수를 디버깅해야합니다.

+0

많은 점에 대해 감사드립니다. 분명히 보인다 (당장!). 배열을 생성 한 후에 배열을 인쇄했는데 기대했던 경계를 모두 따라 잘 보였다. 나는 그것으로 약간의 미정의 값을 얻었는지/볼 방법에 대해 좀 더 알아볼 것입니다. – guthrie

+0

데이터 설정이 잘못되었습니다. 오류 메시지를 잘못 해석했습니다. – guthrie

5

하스켈은 게으른 언어 (*)입니다. trace1trace2을 계산에 사용하지 않으므로 계산되지 않으며 아무 것도 인쇄되지 않습니다. 예를 들어

, 당신은

let is = take 4 $ iterate s trace1 

다음 trace1이 사용됩니다 함께

let is = take 4 $ iterate s i 

를 교체하고 메시지를 추적로 연결되어야합니다.

(*)보다 정확하게, 오늘날 가장 많이 사용되는 Haskell 구현은 하스켈의 엄격하지 않은 의미를 얻기 위해 지연 평가를 사용합니다. 이것이 말이되지 않으면 신경 쓰지 마라.