les*_*how 3 transpose functional-programming list elm
我有一份整体清单清单 [[1,2,3,4],[1,2,3,4]]
我想转发它 [[1,1],[2,2],[3,3]...]
我有:
transpose : List (List a) -> List (List a)
transpose ll = case ll of
((x::xs)::xss) -> (x :: (List.map List.head xss)) :: transpose (xs :: (List.map List.tail xss))
otherwise -> []
Run Code Online (Sandbox Code Playgroud)
但问题是编译器不喜欢head和tail操作,并希望返回Maybe类型.
如何在榆树中正确转置列表?
这取决于......
考虑到所有的边缘箱,你想彻底做到这一点吗?或者快速而肮脏的方式呢?我所谓的边缘案例是列表的列表,其中子列表具有不同的长度.
在边缘情况下,您会遇到程序崩溃
unsafeHead l =
case l of
(h :: t) -> h
_ -> Debug.crash "unsafeHead called with empty list"
unsafeTail l =
case l of
(h :: t) -> t
_ -> Debug.crash "unsafeTail called with empty list"
transpose ll =
case ll of
((x::xs)::xss) ->
let
heads =
List.map unsafeHead xss
tails =
List.map unsafeTail xss
in
(x :: heads) :: transpose (xs :: tails)
_ ->
[]
Run Code Online (Sandbox Code Playgroud)
祝那些随机程序崩溃好运,不要说我没有警告你!
在边缘情况下,您会得到: transpose [[10,11],[20],[],[30,31,32]] == [[10,20,30],[11,31],[32]]
transpose ll =
case ll of
[] ->
[]
([] :: xss) ->
transpose xss
((x::xs) :: xss) ->
let
heads =
List.filterMap List.head xss
tails =
List.filterMap List.tail xss
in
(x :: heads) :: transpose (xs :: tails)
Run Code Online (Sandbox Code Playgroud)
Maybe在边缘情况下,你得到一个 Nothing
如果你只希望当你有所有子列表的大小相同列表的列表来转,你可以提上Maybe您从映射获得与S List.head/ List.tail:
transpose : List (List a) -> Maybe (List (List a))
transpose ll =
case ll of
((x::xs)::xss) ->
let
heads =
xss
|> List.map List.head
|> insideout
tails =
xss
|> List.map List.tail
|> insideout
in
(x #^ heads) ^#^ ((xs #^ tails) `Maybe.andThen` transpose)
_ ->
if ll == List.filter List.isEmpty ll then
Just []
else
Nothing
----- Some helper functions: -----
mCons : a -> Maybe (List a) -> Maybe (List a)
mCons v ml = Maybe.map ((::) v) ml
v #^ ml = mCons v ml
-- this is really a Maybe.map2 (::) mv ml
-- but the standard library doesn't provide map2 :(
m2Cons : Maybe a -> Maybe (List a) -> Maybe (List a)
m2Cons mv ml =
case (mv,ml) of
(Just v, Just l) -> Just (v :: l)
_ -> Nothing
mv ^#^ ml = m2Cons mv ml
-- list of justs to just of list
insideout : List (Maybe a) -> Maybe (List a)
insideout l =
case l of
[] -> Just []
((Just v) :: tail) -> v #^ insideout tail
(Nothing :: _) -> Nothing
Run Code Online (Sandbox Code Playgroud)