您有时可以使用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]]
在矩阵格式良好的情况下,两者都同样有效,因此如果您想检查边缘情况并执行其他操作,您可以先执行此操作。他们只是处理边缘情况略有不同。