2016-03-29 4 views
1

Следующий кортеж:Передача кортежа каррированной функции

val i = (1, 2, 3, 4, 5, 6) 

необходимо передать в качестве параметра каррированной функции следующим образом:

f("param") (i) 

При определении выделанной функции, какой это правильный способ определить тип параметра, который получает кортеж?

def f(s:String) (myTuple:???) = { 
    val (a, b, c, d, e. f) = myTuple 
    // more code 
} 

Я хочу, чтобы избежать имея указать количество и тип каждого elememt в кортеже при определении типа параметра. Другими словами, я хочу, чтобы избежать этого:

def f(s:String) (myTuple:(Int, Int, Int, Int, Int, Int)) = { 
    val (a, b, c, d, e. f) = myTuple 
    // more code 
} 

Благодаря

+1

'(Int, Int, Int, Int, Int, Int)'. И это не имеет никакого отношения к карри. –

+0

, и эта строка '(a, b, c, d, e. F) = myTuple' должна быть' val (a, b, c, d, e, f) = myTuple' –

+0

Я хочу, чтобы не было необходимости указывать количество и тип каждого элемента кортежа. Не лучший способ? Я понимаю, что для non curried функций можно использовать ключевое слово 'tupled'. – user1052610

ответ

4
val i = (1, 2, 3, 4, 5, 6) 

def f(s:String)(myTuple: (Int, Int, Int, Int, Int, Int)) = { 
    val (a, b, c, d, e, f) = myTuple 
} 

f("param")(i) 

Карринг не изменит способ объявить параметры функции так или иначе:

val i = (1, 2, 3, 4, 5, 6) 

def f(myTuple: (Int, Int, Int, Int, Int, Int)) = { 
    val (a, b, c, d, e, f) = myTuple 
} 

f(i) 

Поскольку у вас есть шесть параметров , Я предлагаю вам использовать класс case для документирования их значения:

case class Params(p1: Int, p2: Int, someFancyName: Int, otherName: Int, p5: Int, p6: Int) 

def f(myTuple: Params) = { 
    val Params(a, b, c, d, e, f) = myTuple 
} 

val i = (1, 2, 3, 4, 5, 6) 

f(Params.tupled(i)) 

ваш параметр функции будет понятно, легче от кого называет это потому, что каждый параметр имеет имя в классе случае

Я вижу, вы редактировали свой вопрос: если вы хотите, чтобы избежать указания количества элементов, которые вы можете использовать что-то как образец магнита, и применять магнит для каждого кортежа, или вы можете использовать макросы.

Если вы используете шаблон магнита, вам придется реализовать множество различных реализаций, в зависимости от количества и типа аргументов (вы не можете быть универсальными в своей реализации, вы должны знать, что делать с вашим аргументы). Это короткий пример для кортежей до трех пунктов:

abstract class TupleMagnet[T](t: T) { 
    def apply(): Unit 
} 

object TupleMagnet { 
    implicit def tuple1Magnet[A](t: Tuple1[A]) = new TupleMagnet(t) { 
    def apply() = { println(t._1) } 
    } 
    implicit def tuple2Magnet[A, B](t: (A, B)) = new TupleMagnet(t) { 
    def apply() = t match { case (a, b) => println(""+a + b) } 

    } 
    implicit def tuple3Magnet[A, B, C](t: (A, B, C)) = new TupleMagnet(t) { 
    def apply() = t match { case (a, b, c) => println(""+a + b + c) } 
    } 
} 


def f[T](magnet: TupleMagnet[T]) = magnet() 

val i = (1, 2, 3) 
f(i) 

val j = (1, 2) 
f(j) 

Другой вариант порождающим в число/тип параметров можно с помощью shapelessHList с или Records и реализации Polymorphic function value или что-то подобное.

+0

Спасибо, Джованни. Класс case будет работать, но он просто кажется излишним. – user1052610

+0

@ user1052610 \t Я добавил еще несколько вариантов, которые еще более переполнены: D Scala - это статически типизированный язык, типы и количество аргументов должны быть известны во время компиляции –

+0

Hhmm. Пока я буду придерживаться класса case. Благодаря! – user1052610