понимание отладочного списка - PullRequest
0 голосов
/ 12 сентября 2011

Я скопировал решение Euler.11, данное для (http://www.haskell.org/haskellwiki/Euler_problems/11_to_20#Problem_11),, но это не удалось с ошибкой индексации: " (Array.!): Неопределенный элемент массива ". Конечно, сначала я 'Мне бы хотелось более качественное сообщение об ошибке (!), возможно, даже с указанием неуспешного индекса, но не удалось, что я попытался отладить его.

Данные введены правильно, и в распечатке показаны правильные границы и данные.

Поэтому я добавил несколько сообщений трассировки как к выражению результата, так и к телу понимания. Я получил много результатов трассировки из окончательного выражения, но ни одного из вычислений тела. Почему?

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 ]

5 голосов
/ 12 сентября 2011

Хаскель - ленивый язык (*).Вы не используете trace1 и trace2 в своих вычислениях, поэтому они не оцениваются и ничего не печатается.

Например, если вы замените

let is = take 4 $ iterate s i

с

let is = take 4 $ iterate s trace1

, тогда будет использоваться trace1, что должно привести к трассировке сообщений.

(*) Точнее, GHC, реализация Haskell, наиболее используемая сегодня, использует lazyоценка для достижения строгой семантики Haskell.Не берите в голову, если это не имеет смысла.

2 голосов
/ 12 сентября 2011

Во-первых, для включения в сообщение об ошибке индекса с ошибкой потребуется добавить ограничение Show к индексам массива, что может быть нежелательным.

Во-вторых, как сказал Роман, сообщения не печатаются из-за ленивой оценки. Паттерны взрыва (let !trace = check "i: " i) могут быть наиболее удобным способом обойти это, но я не знаю точно, как они работают в списках.

Далее, сообщение undefined array element сообщает, что массив был построен неправильно (некоторые элементы остались неопределенными), поэтому вам нужно отлаживать функцию, которая его создает, а не функцию, использующую его.

...