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转换为记录。