考虑
type alias Rec = { a: Int, b: Int, c:Int }
updateRec r aVal = { r|a = aVal }
updateRec2 r aVal bVal = { r|a = aVal, b= bVal }
updateRec3 r aVal bVal cVal = ...
如何将updateRec
和updateRec2
...概括为一个函数?
答案 0 :(得分:2)
您想编写一个具有可变数量的不同类型参数的函数。这在动态类型语言(Javascript,Python,Ruby)中很常见,但通常不允许使用类型语言。榆树不允许这样做。
您可以使用Maybe
类型模拟可变数量的不同类型参数,将Nothing
理解为"缺少参数":
updateRec : Rec -> Maybe Int -> Maybe Int -> Maybe Int -> Rec
updateRec r a b c =
{ r
| a = a |> Maybe.withDefault r.a
, b = b |> Maybe.withDefault r.b
, c = c |> Maybe.withDefault r.c
}
如果记录字段的类型相同(此处为Int
),则可以接受List Int
:
updateRec : Rec -> List Int -> Rec
updateRec r fields =
case fields of
[a] -> { r | a = a }
[a,b] -> { r | a = a, b = b }
[a,b,c] -> { r | a = a, b = b, c = c }
_ -> r
我不喜欢这个解决方案,因为如果你不小心提供了包含0或4+元素的列表,它会无声地失败。如果此功能对您有帮助,也许最好先使用List Int
而不是Rec
。
答案 1 :(得分:2)
这是做同样事情的更好方法:
updateA : Int -> Rec -> Rec
updateA x rec = { rec | a = x }
-- Similarly for b, c
现在您可以执行以下操作,假设您已经有了要更新的值rec : Rec
:
myUpdatedRec : Rec
myUpdatedRec =
rec
|> updateA 7
|> updateB 19
现在,您可以通过将|> updateX ...
串联起来来更新任意数量的字段。
答案 2 :(得分:1)
Elm的记录更新语法似乎正是您正在寻找的。你"传入"您想要更新的记录,r
,您可以返回包含您想要更改的字段的记录,而无需指定每个字段:
ex1 = { r|a = 1 }
ex2 = { r|b = 2, c = 3 }
您不需要创建一组附加功能,以便在特定时间仅更新某些字段,因为Elm的记录更新语法是那个通用功能。