Elm 将记录分解为自定义变量名

Elm 将记录分解为自定义变量名,elm,Elm,考虑这一功能: 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 :

考虑这一功能:

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
的一部分,所以我编辑了它

您可以使用属性名销毁
记录
。 如果有多个值,那么您必须有一些助手。 下面的示例中,我定义了
toTuple
来实现这一点

导入颜色曝光(颜色)
三重{红、绿、蓝、阿尔法}
=(红、绿、蓝、阿尔法)
混合:颜色->颜色->颜色
混合c1和c2=
让

(r1,g1,b1,a1)=toTuple我很难弄清楚这是否可能,并且意识到字段访问器非常强大,根本不重要

您的代码可能看起来像:

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 =
  { 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
  }
这些情况是否比:


您提出的解决方案应该有效。。。你试过了吗?也许我提出的问题不好,但不,这不会编译。它将失败,例如:
此let表达式中有多个名为“alpha”的值。
我试图将每个记录的值分解为各自不同的名称。所谓“建议的解决方案”,我的意思是使用
g1
g2
,等等。我在分解记录,而不是元组。位置不匹配,名字匹配。也许我想用一种假设的语法更好地表达:
让{r1=red,g1=green,b1=blue,a1=alpha}=torgbc1…
,这是不可能的。似乎最简单的解决方案是为从
toRgb
返回的记录指定名称,然后使用点访问器访问函数体中的值。
Color
不是任意类型,
toRgb
不是任意函数——它们来自核心库,是唯一的函数访问rgba频道的方法是将其转换为记录。这看起来是一个不错的解决方案。您仍然需要一个let语句将输入
Color
s转换为记录。