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



考虑这个函数:

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
        ...

我很难弄清楚这是否可能,并意识到字段访问器是如此强大,所以这并不重要。

你的代码可能看起来像这样:

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
  }

EDIT:我没有意识到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允许您通过构造函数进行模式匹配。例如

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

最新更新