Иногда вы можете использовать List.take 1
/List.drop 1
вместо List.head
/List.tail
в тех случаях, когда имеет смысл получить пустое List
вместо Nothing
.
В примере transpose
, если вы хотите написать его таким образом, чтобы он удалял любые лишние значения, когда списки не имеют одинаковой длины (т.е. транспонировать только «насколько это возможно» в зависимости от кратчайшего списка), вы можете использовать:
transpose : List (List a) -> List (List a)
transpose ll =
let heads = List.map (List.take 1) ll |> List.concat
tails = List.map (List.drop 1) ll
in
if | List.length heads == List.length ll ->
heads::(transpose tails)
| otherwise ->
[]
transpose [[1,2,3,4],[1,2,3,4]] --> [[1,1],[2,2],[3,3],[4,4]]
transpose [[10,11],[20],[],[30,31,32]] --> []
Если вы хотите, чтобы он продолжал брать из списков до тех пор, пока они все не исчезнут (т.е. транспонировать «насколько это возможно» в зависимости от самого длинного списка), вы можете использовать:
transpose : List (List a) -> List (List a)
transpose ll =
let heads = List.map (List.take 1) ll |> List.concat
tails = List.map (List.drop 1) ll
in
if | List.isEmpty heads ->
[]
| otherwise ->
heads::(transpose tails)
transpose [[1,2,3,4],[1,2,3,4]] --> [[1,1],[2,2],[3,3],[4,4]]
transpose [[10,11],[20],[],[30,31,32]] --> [[10,20,30],[11,31],[32]]
Оба будут работать одинаково хорошо в случае, если матрица правильно сформирована, поэтому, если вы хотите проверить крайние случаи и сделать что-то еще, вы можете сделать это в первую очередь. Они просто обрабатывают крайние случаи немного по-другому.
person
robertjlooby
schedule
12.08.2015