Преобразование Списка (Может быть) в Возможно (Список) в Вязе - PullRequest
0 голосов
/ 28 октября 2018

Какой хороший способ конвертировать 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 голосов
/ 29 октября 2018

@ Чад Гилберт ответ, конечно, правильный, но если вы ищете более простую реализацию такой функции, то следующая строка поможет:

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)

Обратите внимание, что (::) функция (prepend to list) используется вместо (++) или List.append, потому что это более производительно для списков.Тогда foldr должен использоваться вместо foldl для сохранения заказа.

0 голосов
/ 28 октября 2018

Вы можете использовать инструмент Elm Fancy Search и искать по сигнатуре функции: %20Maybe%20(List%20a)" rel="nofollow noreferrer"> Список (может быть) -> Возможно (список а)

Первый результат появляется Maybe.Extra.combine

...