使用默认值映射Maybes

时间:2018-04-26 14:46:06

标签: functional-programming elm

我是榆树和fp的新手,所以我想弄明白

我正在尝试解码一个可能有两个可选文件的Json"用户名"和#34;密码"其中

我成功地将结构解码为以下类型

type alias Req = 
    { ...
    , username : Maybe String
    , password: Maybe String
    }

我还有其他类型

type alias BA = 
     { username : String
     , password : String
     }

type alias sBA = Maybe BA

现在我想要一个函数getsBa,以便我可以执行以下操作

getsBA : Req -> sBA
...

a : Req
a = { ...
     , username = Just "test"
     , password = Nothing
     }

getsBA a == Just { username = "test", password = "" }

b = { ...
     , username = Nothing
     , password = Nothing
     }
 getsBA b = Nothing

c : Req
c = { ...
     , username = Nothing
     , password = Just "123"
     }

getsBA a == Just { username = "", password = "123" }


d : Req
d = { ...
     , username = Just "test"
     , password = Just "123"
     }

getsBA a == Just { username = "test", password = "123" }

如何从FP方面考虑这样的解决方案?

2 个答案:

答案 0 :(得分:3)

type alias Creds = (Maybe String, Maybe String)
f :: Req -> Creds
f r = (r.username, r.password)

g :: Creds -> sBA
g c = 
  case c of
    (Nothing, Nothing) -> Nothing
    (Nothing, Just p) -> Just {username = "", password = p}
    (Just u, Nothing) -> Just {username = u, password = ""}
    (Just u, Just p) -> Just {username = u, password = p}

getsBA = g << f

f是字段提取器,g操纵这些值,getsBA是这两个值的组合(提取字段然后操纵它们)。

答案 1 :(得分:0)

这是@ duggi的答案的替代方案,它使用Maybe.withDefault来减少代码中的重复:

getsBA : Req -> SBA
getsBA { username, password } =
    case ( username, password ) of
        ( Nothing, Nothing ) ->
            Nothing

        _ ->
            Just <| BA (Maybe.withDefault "" username) (Maybe.withDefault "" password)