是否有一种不那么冗长的方式来解开榆树中的可能值

时间:2016-11-15 00:48:25

标签: functional-programming elm

我在elm中经常遇到一个问题,我有一个函数依赖于多个可能值为Just。是否有一种不那么冗长的方式来编写这段代码:

commandIf apples bananas oranges =
        case apples of
            Just apples_ ->
                case bananas of
                    Just bananas_ ->
                        case oranges of
                            Just oranges_ ->
                                someCommand apples_ bananas_ oranges_

                            Nothing ->
                                Cmd.none

                    Nothing ->
                        Cmd.none

            Nothing ->
                Cmd.none

3 个答案:

答案 0 :(得分:9)

如果您同时需要所有三个值,则可以将它们作为元组匹配,并将所有其他组合(当其中一个或多个Nothing)保留为后备情况时:

commandIf apples bananas oranges =
  case (apples, bananas, oranges) of
    (Just apples_, Just bananas_, Just oranges_) ->
        someCommand apples_ bananas_ oranges_

    _ ->
        Cmd.none

答案 1 :(得分:9)

@ laughedelic的回答非常好。只是想提供一些替代的和更通用的解决方案,因为详细Maybe展开是我在Elm开始时遇到的一个问题。

如果您有固定数量的Maybe,则可以使用map2, map3等来执行您想要的操作(docs here):

commandIf apples bananas oranges =
  Maybe.map3 someCommand apples bananas oranges
  |> Maybe.withDefault Cmd.none

这里,someCommand是你的函数,它接受3个参数,并返回一些命令。

仅当所有3个变量都是Maybe.map3时,

Just x才会应用此函数,并将其包装在一个Maybe类型中。因此,如果所有3都有值,则结果为Just (someCommand apples bananas oranges)。否则,该函数返回Nothing

然后,这个结果是"管道"进入Maybe.withDefault。如果输入为Cmd.none,则返回Nothing,否则返回值(您的命令),而不是Just

如果您有未知长度的Maybe列表,您可以执行以下操作:

keepOnlyJusts : List (Maybe a) -> List a
keepOnlyJusts listOfMaybes =
  listOfMaybes
  |> List.filterMap identity

newList = keepOnlyJusts [ Just 1, Nothing, Just 3 ]   -- == [1,3]

其中结果是一个列表(可能为空),其中只保留值。

答案 2 :(得分:-1)

Maybe.map3解决了您的具体情况,但这个答案是关于使用Maybe.andThen 链接可能值的一般模式。

commandIf a_ b_ c_ =
  a_ |> Maybe.andThen (\a ->
    b_ |> Maybe.andThen (\b ->
      c_ |> Maybe.andThen (Just << someCommand a b)))
  |> Maybe.withDefault Cmd.none