是否可以写出类似C++的东西
template <typename... T> std::string dup(int n, std::string s, T... tail) {
std::string result;
for (int i = 0; i < n; ++i) {
result += s;
}
if constexpr (sizeof...(tail) == 0) {
return result;
} else {
return result + dup(tail...);
}
}
std::cout << dup(1, std::string("abc"), 2, std::string("xyz"), 3, std::string("a")) << std::endl; // abcxyzxyzaaa
我尝试在 TypedRacket 中编写以下函数
#lang typed/racket
(: repeat-string (-> Integer String String))
(define (repeat-string n str)
(apply string-append (build-list n (λ (_) str))))
(: dup (All (T ...) (-> Integer String T ... T String)))
(define (dup n s . tail)
(define result (repeat-string n s))
(cond [(empty? tail) result]
[else (string-append result (apply dup tail))])
)
但我有类型检查错误:
Type Checker: Bad arguments to function in 'apply': Domain: Integer String T ... T Arguments: (List T ... T) in: (apply dup tail)
老实说,我不明白为什么争论是(List T ... T)
但不是(T ... T)
。而且,函数是正确的,非类型化的 Racket 产生正确的结果
->*
以适当的类型安全实现此目的的关键是使用关键字指定函数的类型#:rest-star
:如果您的函数直接采用列表,则可以使用
Rec
和List*
来创建类型签名。然后您还可以根据dup
它来定义: