Vous pouvez parfois utiliser List.take 1
/List.drop 1
en place de List.head
/List.tail
dans les cas où il peut être plus logique d'obtenir un vide List
au lieu de Nothing
. Dans l'exemple de transpose
, si vous voulez l'écrire de manière à supprimer des valeurs supplémentaires lorsque les listes n'ont pas la même longueur (c'est-à-dire transposer "autant que possible" selon la liste la plus courte), vous pouvez utiliser:
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]] --> []
Si vous le voulez continuer à prendre des listes jusqu'à ce qu'ils soient tous partis (transposer « autant que possible » en fonction de la plus longue liste), vous pouvez utiliser:
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]]
Les deux fonctionneront aussi bien dans le cas où la matrice est bien formé, donc si vous voulez vérifier les cas de bord et faire quelque chose d'autre, vous pouvez le faire en premier. Ils manipulent juste les cas de bord un peu différemment.