在榆木中将清单(也许是a)转换为也许(清单a)

时间:2018-10-28 13:29:32

标签: algorithm list elm maybe

在榆木中将List (Maybe a)转换为Maybe (List a)的好方法是什么?

逻辑很简单:

  • 如果所有项目均为Just (List a),请返回Just a
  • 否则,返回Nothing
Example 1:

input:  [ Just 1, Just 2, Just 3 ]
output: Just [ 1, 2, 3 ]

Example 2:

input:  [ Just 1, Nothing, Just 3 ]
output: Nothing

可以使用某些内置功能轻松完成吗?

我想出的最好的样子是这样的:

listOfMaybesToMaybeList : List (Maybe a) -> Maybe (List a)
listOfMaybesToMaybeList listOfMaybes =
    List.foldl
        (\maybeItem ->
            \maybeResultList ->
                case ( maybeItem, maybeResultList ) of
                    ( Just item, Just resultList ) ->
                        Just (List.append resultList [ item ])

                    ( _, _ ) ->
                        Nothing
        )
        (Just [])
        listOfMaybes

这种函数的合适名称是什么?在寻找答案时,我发现Haskell中有一个名为sequence的函数,似乎在做类似的事情。

2 个答案:

答案 0 :(得分:4)

您可以使用Elm Fancy Search工具并搜索功能签名:List (Maybe a) -> Maybe (List a)

第一个结果出现Maybe.Extra.combine

答案 1 :(得分:4)

@Chad Gilbert的答案肯定是正确的,但是如果您正在寻找这种功能的更简单的实现,那么下面的代码就可以解决问题:

listOfMaybesToMaybeList : List (Maybe a) -> Maybe (List a)
listOfMaybesToMaybeList listOfMaybes =
    List.foldr (Maybe.map2 (::)) (Just []) listOfMaybes

或者只是:

listOfMaybesToMaybeList : List (Maybe a) -> Maybe (List a)
listOfMaybesToMaybeList = List.foldr (Maybe.map2 (::)) (Just [])

Maybe.map2仅接受一个函数和两个Maybe值并将该函数应用于这些值:

> Maybe.map2 (+) (Just 2) (Just 3)
Just 5 : Maybe.Maybe number
> Maybe.map2 (::) (Just 2) (Just [1])
Just [2,1] : Maybe.Maybe (List number)

请注意,使用(::)函数(在列表之前)代替了(++)List.append,因为它在列表中表现更好。然后必须使用foldr而不是foldl来保持顺序。