Aplicar uma lista de argumentos à função ao curry usando foldLeft no Scala

É possível fazer umfoldLeft em uma lista de argumentos, onde o valor inicial fornecido para a dobra é uma função totalmente curry, o operador éapply e a lista é uma lista de argumentos a serem passados para a funçãof?

Por exemplo, digamos que f é definido como:

scala> val f = (i: Int, j: Int, k: Int, l: Int) => i+j+k+l
f: (Int, Int, Int, Int) => Int = <function4>

Qual é claro que podemos usar diretamente:

scala> f(1, 2, 3, 4)
res1: Int = 10

O curry e aplique os argumentos um de cada vez:

scala> f.curried
res2: Int => Int => Int => Int => Int = <function1>

scala> f.curried.apply(1).apply(2).apply(3).apply(4)
res3: Int = 10

À primeira vista, isso parece um trabalho parafoldLeft.

Minha primeira tentativa de descrever esta sequência deapply usandofoldLeft parece

scala> List(1, 2, 3, 4).foldLeft(f.curried)({ (g, x) => g.apply(x) })

No entanto, isso gera o seguinte erro:

<console>:9: error: type mismatch;
 found   : Int => Int => Int => Int
 required: Int => Int => Int => Int => Int
              List(1, 2, 3, 4).foldLeft(f.curried)({ (g, x) => g.apply(x) })

Minha leitura da mensagem de erro é que a inferência de tipo precisaria de alguma dica parag.

A solução que estou procurando deixa tudo não modificado na minha expressão original, exceto o tipo deg:

List(1, 2, 3, 4).foldLeft(f.curried)({ (g: ANSWER, x) => g.apply(x) })

Meu primeiro pensamento foi que um tipo de união seria útil aqui. Eu já vi a derivação de tipos de união de Miles Sabin usando Curry-Howard; portanto, se esse primeiro palpite é verdadeiro, parece que tenho o mecanismo básico necessário para resolver o problem

No entanto: Mesmo que os tipos de união sejam a resposta, seria útil se eu pudesse me referir a "A união de todos os tipos, desde o tipo de função totalmente com curry ao tipo de função com curry, com exceção do último argumento fornecido". Em outras palavras, uma maneira de transformar o tipo:

T1 => ... => Tn

no tipo de união:

(T1 => ... => Tn) |∨| ... |∨| (Tn-1 => Tn)

seria útil como o tipo parag acima

Fazer umfoldLeft com umList limita a discussão ao caso em queT1 atravésTn-1 são todos iguais. Uma notação como

(T1 =>)+ Tn

descreveria o tipo que eu quero fornecerg.

O caso específico sobre o qual estou perguntando não exige cadeias arbitrariamente longas, para que possamos fornecer limites ao iterador usando

(T1 =>){1,4} Tn

Esperando ansiosamente fazer isso por cadeias de tipos que não são iguais, talvez seja útil alguma função mágica em tipos que agrupam a cadeia no conjunto de todos os sufixos:

Suffixes(T1 => ... => Tn)

Implementar isso está muito além das minhas habilidades no Scala no momento. Qualquer sugestão sobre como fazê-lo seria apreciada. Se isso pode ser feito com o uso avançado do sistema de tipos existente do Scala ou por meio de um plug-in de compilador ou não, eu não se

As foi observado nos comentários abaixo, chamar o resultado de "tipo de união" não é o ajuste perfeito para este caso de uso. Não sei mais o que chamar, mas essa é a ideia mais próxima que tenho no momento. Outros idiomas têm suporte especial para essa ideia? Como isso funcionaria na Coq e na Agda?

Nomear esse problema e entender onde ele se encontra em relação à visão geral (da teoria dos tipos, da decidibilidade etc.) é mais importante para mim do que ter uma implementação funcional deANSWER, embora ambos sejam legais. O bônus aponta para qualquer pessoa que possa estabelecer conexões com Scalaz, Monoids ou Teoria da Categoria em gera

questionAnswers(3)

yourAnswerToTheQuestion