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

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

上面的方法不起作用,因为它引入了重复的变量名。 是否可以将上述值解构为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
        ...

编辑: 我没有意识到 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)

我很难弄清楚这是否可行,并意识到字段访问器是如此强大以至于它无关紧要。

大概您的代码可能类似于:

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
  }