É possível escrever algo semelhante ao 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
Tentei escrever a seguinte função em 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))])
)
mas tenho um erro de verificação de digitação:
Type Checker: Bad arguments to function in 'apply': Domain: Integer String T ... T Arguments: (List T ... T) in: (apply dup tail)
Honestamente, não entendo por que os argumentos existem, (List T ... T)
mas não (T ... T)
. Além disso, a função está correta, Racket não digitado produz os resultados corretos
A chave para fazer isso com segurança de tipo adequada é especificar o tipo de sua função usando
->*
uma#:rest-star
palavra-chave:Se sua função recebe uma lista diretamente, você pode usar
Rec
eList*
para criar a assinatura de tipo. Você também pode definirdup
em termos disso: