Это матричное перемещение функционирует работы, но я пытаюсь понять его пошаговый execurtion, и я не получаю его.
transpose:: [[a]]->[[a]]
transpose ([]:_) = []
transpose x = (map head x) : transpose (map tail x)
с
transpose [[1,2,3],[4,5,6],[7,8,9]]
это возвращается:
[[1,4,7],[2,5,8],[3,6,9]]
Я не добираюсь, как оператор конкатенации работает с картой. Это связывает каждого главу x в том же вызове функции? Как?
это
(map head x)
создание списка главных элементов каждого списка?
Давайте посмотрим, что функция делает для вашего примера ввода:
transpose [[1,2,3],[4,5,6],[7,8,9]]
<=>
(map head [[1,2,3],[4,5,6],[7,8,9]]) : (transpose (map tail [[1,2,3],[4,5,6],[7,8,9]]))
<=>
[1,4,7] : (transpose [[2,3],[5,6],[8,9]])
<=>
[1,4,7] : (map head [[2,3],[5,6],[8,9]]) : (transpose (map tail [[2,3],[5,6],[8,9]]))
<=>
[1,4,7] : [2,5,8] : (transpose [[3],[6],[9]])
<=>
[1,4,7] : [2,5,8] : (map head [[3],[6],[9]]) : (transpose (map tail [[3],[6],[9]]))
<=>
[1,4,7] : [2,5,8] : [3, 6, 9] : (transpose [[], [], []])
<=>
[1,4,7] : [2,5,8] : [3, 6, 9] : [] -- because transpose ([]:_) = []
<=>
[[1,4,7],[2,5,8],[3,6,9]]
Обратите внимание, что порядок, в котором я решил сократить количество терминов, не совпадает с порядком оценки, который будет использовать haskell, но это не меняет результат.
Изменить: В ответ на ваш отредактированный вопрос:
это
(заголовок карты x)
, создающий список элементов заголовка каждого списка?
Да, это является.
Оператор cons :
присоединить объект типа a
к списку типа [a]
. В
(map head x) : transpose (map tail x)
LHS - это список ( a = [b]
), а RHS - это список из списка ( [a] = [[b]]
), поэтому такая конструкция верна. Результатом будет
[x,y,z,...] : [[a,b,...],[d,e,...],...] = [[x,y,z,...], [a,b,...],[d,e,...],...]
В вашем случае заголовок карты x
и хвост карты x
разбивает матрицу
x = [[1,2,3],[4,5,6],[7,8,9]]
на
map head x = [1,4,7]
map tail x = [[2,3],[5,6],[8,9]]
(и да, заголовок карты x
- это список элементов заголовка каждого списка.) 2-я часть транспонируется (подробные инструкции см. В ответе @ sepp2k ), чтобы сформировать
transpose (map tail x) = [[2,5,8],[3,6,9]]
таким образом, чтобы составить [1 , 4,7]
к этому дает
map head x : transpose (map tail x) = [1,4,7] : [[2,5,8],[3,6,9]]
= [[1,4,7] , [2,5,8],[3,6,9]]
ghci
- ваш друг:
*Main> :t map head map head :: [[a]] -> [a] *Main> :t map tail map tail :: [[a]] -> [[a]]
Даже если вы не понимаете map
(проблема, которую вы хотели бы исправить быстро!), Типы этих выражений многое говорят о том, как они работают. Первый - это единственный список, взятый из списка списков, поэтому давайте скормим ему простой вектор, чтобы посмотреть, что произойдет.
Возможно, вы захотите написать
*Main> map head [1,2,3]
, но это не приведет к проверке типа:
<interactive>:1:14: No instance for (Num [a]) arising from the literal `3' at :1:14 Possible fix: add an instance declaration for (Num [a]) In the expression: 3 In the second argument of `map', namely `[1, 2, 3]' In the expression: map head [1, 2, 3]
Помните, что тип аргумента - это список списков, поэтому
*Main> map head [[1,2,3]]
[1]
Немного сложнее
*Main> map head [[1,2,3],[4,5,6]]
[1,4]
То же самое, но с ] tail
вместо head
дает
*Main> map tail [[1,2,3],[4,5,6]]
[[2,3],[5,6]]
Как вы можете видеть, определение transpose
многократно отрезает первую «строку» с помощью head x
, а остальное - map tail x
.