Chapel 中的元组连接
Tuple Concatenation in Chapel
假设我正在生成元组并且我想在它们出现时连接它们。我该怎么做呢?以下是逐元素加法:
if ts = ("foo", "cat")
, t = ("bar", "dog")
ts += t
给出 ts = ("foobar", "catdog")
,
但我真正想要的是ts = (("foo","cat"),("bar","dog"))
。
所以我猜第一个问题是"does Chapel support tuple concatention?",然后是"is there a binary operator/function for it?",然后是"if not, what is a good way to do it?",最后是"make my life easier if you know a better way of living"。
请按顺序回答问题。
非常感谢您的帮助!!
the first question is "does Chapel support tuple concatention?"
我相信这里的答案是 "no",原因如下:(1) Chapel 变量有一个单一的静态类型,在其生命周期内不能改变,(2) 元组的类型被定义为它的元素的静态数量以及每个元素的类型。因此,给定您的变量 ts
ts = ("foo", "cat")
它的类型是 2*string
("a 2-tuple of strings"),这将阻止它存储值 (("foo","cat"),("bar","dog"))
,因为 它类型是 2*(2*string)
("a 2-tuple of 2-tuples of strings")。因此,虽然这两个元组具有相同数量的元素 (2),但它们的元素类型不同("string" 与“字符串的 2 元组”),因此类型不同(不兼容).
"is there a binary operator/function for it?"
由于上述原因,没有。
then "if not, what is a good way to do it?"
我想到了一些事情,但可能有用也可能没有用,具体取决于您的具体情况。与其尝试重新分配 ts
,不如创建一个元组中的元组的新元组:
const ts2 = (ts, t);
你甚至可以在例程中递归地执行此操作,但如果元组增长到任何显着长度,这可能最终会导致代码大小膨胀(因为每次调用函数都会生成不同类型的元组以及它的唯一代码)。
根据我在您的问题中看到的内容,我认为您可能想要使用元组列表或元组的一维数组(向量)。这是一个基于列表的方法:
use List;
var listOfTups: list(2*string);
listOfTups.append(("foo", "cat"));
listOfTups.append(("bar", "dog"));
writeln(listOfTups);
这是一种基于数组的方法:
var arrOfTups: [1..0] 2*string;
arrOfTups.push_back(("foo", "cat"));
arrOfTups.push_back(("bar", "dog"));
writeln(arrOfTups);
在这两者中,我会推荐基于数组的方法,因为数组更优先 class 并且在 Chapel 中功能强大(它们享有句法支持、允许数据并行性、支持标量函数和运算符的提升等),而列表只是一个方便的库。
and lastly "make my life easier if you know a better way of living".
如果您不知道,我想提的另一件事是 Chapel 中的 "varargs" 函数有效地将这些参数转换为元组。所以给出:
proc myFunc(x...) {
writeln(x.type:string);
}
myFunc(("foo", "cat"), ("bar", "dog"));
输出为:
2*2*string
假设我正在生成元组并且我想在它们出现时连接它们。我该怎么做呢?以下是逐元素加法:
if ts = ("foo", "cat")
, t = ("bar", "dog")
ts += t
给出 ts = ("foobar", "catdog")
,
但我真正想要的是ts = (("foo","cat"),("bar","dog"))
。
所以我猜第一个问题是"does Chapel support tuple concatention?",然后是"is there a binary operator/function for it?",然后是"if not, what is a good way to do it?",最后是"make my life easier if you know a better way of living"。
请按顺序回答问题。
非常感谢您的帮助!!
the first question is "does Chapel support tuple concatention?"
我相信这里的答案是 "no",原因如下:(1) Chapel 变量有一个单一的静态类型,在其生命周期内不能改变,(2) 元组的类型被定义为它的元素的静态数量以及每个元素的类型。因此,给定您的变量 ts
ts = ("foo", "cat")
它的类型是 2*string
("a 2-tuple of strings"),这将阻止它存储值 (("foo","cat"),("bar","dog"))
,因为 它类型是 2*(2*string)
("a 2-tuple of 2-tuples of strings")。因此,虽然这两个元组具有相同数量的元素 (2),但它们的元素类型不同("string" 与“字符串的 2 元组”),因此类型不同(不兼容).
"is there a binary operator/function for it?"
由于上述原因,没有。
then "if not, what is a good way to do it?"
我想到了一些事情,但可能有用也可能没有用,具体取决于您的具体情况。与其尝试重新分配 ts
,不如创建一个元组中的元组的新元组:
const ts2 = (ts, t);
你甚至可以在例程中递归地执行此操作,但如果元组增长到任何显着长度,这可能最终会导致代码大小膨胀(因为每次调用函数都会生成不同类型的元组以及它的唯一代码)。
根据我在您的问题中看到的内容,我认为您可能想要使用元组列表或元组的一维数组(向量)。这是一个基于列表的方法:
use List;
var listOfTups: list(2*string);
listOfTups.append(("foo", "cat"));
listOfTups.append(("bar", "dog"));
writeln(listOfTups);
这是一种基于数组的方法:
var arrOfTups: [1..0] 2*string;
arrOfTups.push_back(("foo", "cat"));
arrOfTups.push_back(("bar", "dog"));
writeln(arrOfTups);
在这两者中,我会推荐基于数组的方法,因为数组更优先 class 并且在 Chapel 中功能强大(它们享有句法支持、允许数据并行性、支持标量函数和运算符的提升等),而列表只是一个方便的库。
and lastly "make my life easier if you know a better way of living".
如果您不知道,我想提的另一件事是 Chapel 中的 "varargs" 函数有效地将这些参数转换为元组。所以给出:
proc myFunc(x...) {
writeln(x.type:string);
}
myFunc(("foo", "cat"), ("bar", "dog"));
输出为:
2*2*string