将记录解构为自定义变量名称

时间:2016-09-06 01:40:49

标签: elm

考虑这个功能:

mix : Color -> Color -> Color
mix c1 c2 =
    let 
        { red, green, blue, alpha } = toRgb c1
        { red, green, blue, alpha } = toRgb c2
    in
        ...

以上操作无效,因为它引入了重复的变量名称。 是否可以将上述值解构为r1r2g1g2等?

为了澄清,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
        ...

2 个答案:

答案 0 :(得分:1)

修改 我没有意识到ColorCore的一部分,所以我编辑。

您可以使用属性名称破坏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允许您通过构造函数进行模式匹配。 e.g。

type Color = RGB Int Int Int
purple = RGB 255 0 255
printRedVal =
  case purple of
    RGB r g b -> text (toString r)

答案 1 :(得分:1)

我无法弄清楚这是否可能,并意识到现场存取器是如此强大以至于无关紧要。

据推测,您的代码可能类似于:

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
  }