将记录解构为自定义变量名称
Destructuring records into custom variable names
考虑这个函数:
mix : Color -> Color -> Color
mix c1 c2 =
let
{ red, green, blue, alpha } = toRgb c1
{ red, green, blue, alpha } = toRgb c2
in
...
上面的方法不起作用,因为它引入了重复的变量名。 是否可以将上述值解构为r1
、r2
、g1
、g2
等?
澄清一下,toRgb
有这个签名:
toRgb : Color -> { red:Int, green:Int, blue:Int, alpha:Float }
假设的语法可能会更好地表达我想做的事情:
mix : Color -> Color -> Color
mix c1 c2 =
let
{ red as r1, green as g1, blue as b1, alpha as a1 } = toRgb c1
{ red as r2, green as g2, blue as b2, alpha as a2 } = toRgb c2
in
...
编辑:
我没有意识到 Color
是 Core
的一部分,所以我编辑了。
您可以使用 属性 个名称破坏 Record
。
如果有多个值,那么你必须有一些帮手。
在下面的示例中,我定义了 toTuple
来执行此操作。
import Color exposing (Color)
toTuple {red, green, blue, alpha}
= (red, green, blue, alpha)
mix : Color -> Color -> Color
mix c1 c2 =
let
(r1, g1, b1, a1) = toTuple <| Color.toRgb c1
(r2, g2, b2, a2) = toTuple <| Color.toRgb c2
in
Color.rgba
(avg r1 r2)
(avg g1 g2)
(avg b1 b2)
(avgf a1 a2)
avg i j = (i + j) // 2
avgf p q = 0.5 * (p + q)
原文:
我不确定这是否是您要查找的内容,但是您不需要将其转换为记录。
case of
允许您通过构造函数进行模式匹配。例如
type Color = RGB Int Int Int
purple = RGB 255 0 255
printRedVal =
case purple of
RGB r g b -> text (toString r)
我很难弄清楚这是否可行,并意识到字段访问器是如此强大以至于它无关紧要。
大概您的代码可能类似于:
mix : Color -> Color -> Color
mix c1 c2 =
{ red = avg c1.red c2.red
, green = avg c1.green c2.green
, blue = avg c1.blue c2.blue
, alpha = avg c1.alpha c2.alpha
}
并没有那么可怕或不可读。但是,您甚至可以这样做:
mix : Color -> Color -> Color
mix c1 c2 =
{ red = avg .red c1 c2
, green = avg .green c1 c2
, blue = avg .blue c1 c2
, alpha = avg .alpha c1 c2
}
那些 是否比:
mix : Color -> Color -> Color
mix c1 c2 =
let
{ red1, green1, blue1, alpha1 } = toRgb c1
{ red2, green2, blue2, alpha2 } = toRgb c2
in
{ red = avg red1 red2
, green = avg green1 green2
, blue = avg blue1 blue2
, alpha = avg alpha1 alpha2
}
考虑这个函数:
mix : Color -> Color -> Color
mix c1 c2 =
let
{ red, green, blue, alpha } = toRgb c1
{ red, green, blue, alpha } = toRgb c2
in
...
上面的方法不起作用,因为它引入了重复的变量名。 是否可以将上述值解构为r1
、r2
、g1
、g2
等?
澄清一下,toRgb
有这个签名:
toRgb : Color -> { red:Int, green:Int, blue:Int, alpha:Float }
假设的语法可能会更好地表达我想做的事情:
mix : Color -> Color -> Color
mix c1 c2 =
let
{ red as r1, green as g1, blue as b1, alpha as a1 } = toRgb c1
{ red as r2, green as g2, blue as b2, alpha as a2 } = toRgb c2
in
...
编辑:
我没有意识到 Color
是 Core
的一部分,所以我编辑了。
您可以使用 属性 个名称破坏 Record
。
如果有多个值,那么你必须有一些帮手。
在下面的示例中,我定义了 toTuple
来执行此操作。
import Color exposing (Color)
toTuple {red, green, blue, alpha}
= (red, green, blue, alpha)
mix : Color -> Color -> Color
mix c1 c2 =
let
(r1, g1, b1, a1) = toTuple <| Color.toRgb c1
(r2, g2, b2, a2) = toTuple <| Color.toRgb c2
in
Color.rgba
(avg r1 r2)
(avg g1 g2)
(avg b1 b2)
(avgf a1 a2)
avg i j = (i + j) // 2
avgf p q = 0.5 * (p + q)
原文:
我不确定这是否是您要查找的内容,但是您不需要将其转换为记录。
case of
允许您通过构造函数进行模式匹配。例如
type Color = RGB Int Int Int
purple = RGB 255 0 255
printRedVal =
case purple of
RGB r g b -> text (toString r)
我很难弄清楚这是否可行,并意识到字段访问器是如此强大以至于它无关紧要。
大概您的代码可能类似于:
mix : Color -> Color -> Color
mix c1 c2 =
{ red = avg c1.red c2.red
, green = avg c1.green c2.green
, blue = avg c1.blue c2.blue
, alpha = avg c1.alpha c2.alpha
}
并没有那么可怕或不可读。但是,您甚至可以这样做:
mix : Color -> Color -> Color
mix c1 c2 =
{ red = avg .red c1 c2
, green = avg .green c1 c2
, blue = avg .blue c1 c2
, alpha = avg .alpha c1 c2
}
那些 是否比:
mix : Color -> Color -> Color
mix c1 c2 =
let
{ red1, green1, blue1, alpha1 } = toRgb c1
{ red2, green2, blue2, alpha2 } = toRgb c2
in
{ red = avg red1 red2
, green = avg green1 green2
, blue = avg blue1 blue2
, alpha = avg alpha1 alpha2
}