Почему я получаю «Исключение: Prelude.head: пустой список»? - PullRequest
2 голосов
/ 03 февраля 2011

Не могу понять, почему не работает сопоставление с образцом!Я начинаю с Хаскелла, так что наберитесь терпения!

-- matrix implemented as a list of lists (rows of the matrix)
test_matrix3 = [[1,0,0],[2,-3,0],[4,5,6]]

-- transpose of a given matrix
transpose    (x:[]) = [x]
transpose all@(x:_) = map head all : transpose ([tail y | y <- all])

Выполнение:

*Main> transpose test_matrix3
[[1,2,4],[0,-3,5],[0,0,6],[*** Exception: Prelude.head: empty list

Ответы [ 3 ]

6 голосов
/ 03 февраля 2011
  transpose [[1,0,0],[2,-3,0],[4,5,6]]
= [1,2,4] : transpose [[0,0],[-3,0],[5,6]]
= [1,2,4] : [0,-3,5] : transpose [[0],[0],[6]]
= [1,2,4] : [0,-3,5] : [0,0,0] : transpose [[],[],[]]

И вот где это происходит. Это не соответствует первому шаблону, потому что это не одноэлементный список - это список с тремя элементами. Итак:

= [1,2,3] : [0,-3,5] : [0,0,0] : map head [[],[],[]] : transpose (map tail [[],[],[]])

Что даст вам одну ошибку для каждого пустого списка, поскольку head и tail не определены в пустых списках.

2 голосов
/ 03 февраля 2011

Этот работал для меня:

transpose' ([]:_) = []
transpose' xs = (map head xs) : (transpose' (map tail xs))

Тест:

*Main> transpose' test_matrix3
[[1,2,4],[0,-3,5],[0,0,6]]
1 голос
/ 03 февраля 2011

Учтите, что вы работаете со списком списков. Поэтому ваше первое сопоставление с образцом всегда не выполняется в вашей тестовой матрице. По сути, вы продолжаете брать хвост каждого элемента вашего списка, но это не уменьшает количество элементов в вашем списке, а просто уменьшает их индивидуальный размер.

Чтобы исправить это, вы можете изменить свой первый шаблон, чтобы он соответствовал структуре x.

Помните, списки списков!

...