2013-03-28 7 views
2

Я хотел бы написать функцию, которая может получить неограниченное количество параметров с этим синтаксисомПрименить функцию неограниченных параметров

MyFunc arg1 arg2 arg3 .... Я пробовал некоторые используя curring, но ничего не помогало я попытался сделать его recursivly но компилятор Scala говорит: "рекурсивный Scala потребность метода приводит типа" рекурсивных:

def func(x:Int) = { 
    doSomething(x); myVal:Int=>func(myVal) 
} 

благодарит за хелпер

+0

Любая причина, по которой вы не можете использовать список параметров, а не только неизвестное количество параметров? – us2012

+0

Я не вижу, как этот код мог компилироваться. 'val' является зарезервированным словом в Scala (если вы не закрываете его в обратном тике). Что касается этой диагностики, она должна быть понятной. Непосредственно рекурсивные методы не могут полагаться на вывод типа для получения типа результата метода; вы должны дать это явно. –

ответ

6

Easy:

scala> class FRP1 { def apply(args: Int*) = args.mkString("{", ", ", "}") } 
defined class FRP1 

scala> val frp11 = new FRP1 
frp11: FRP1 = [email protected] 

scala> frp11(1) 
res0: String = {1} 

scala> frp11(1, 2) 
res1: String = {1, 2} 

scala> frp11(1, 2, 3) 
res2: String = {1, 2, 3} 
+0

Это не то, что я хотел, я знаю о Int * Я хотел создать «классный синтаксис» для моего кода, не используя никаких скобок вообще! как я уже сказал: myFunc arg1 arg2 arg3 ..... –

+1

Внутренние DSL все еще Scala. Магии нет. –

6

Так функция вы ищете принимает аргумент определенного типа и должна возвращать функцию, которая принимает аргумент того же типа и возвращает функцию с принимает аргумент того же типа и так далее , до бесконечности.

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

T[X] = X => T[X] 

То есть, это рекурсивный, автореферентно типа. Поскольку он является саморегуляцией, мы должны назвать его с единственной целью повторного использования его внутри себя (к сожалению, Scala не имеет комбинатора с фиксированной запятой для бесконечных типов). Давайте назовем это InfCurry и это выглядит примерно так:

trait InfCurry[T] extends (T => InfCurry[T]) 

Как вы можете видеть, это подражает приведенное выше определение достаточно хорошо (другой вариант был бы псевдонимами типа, но Scala не поддерживает рекурсивный тип-псевдонимов) ,

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

object InfCurry { 
    def apply[T](f: T => InfCurry[T]): InfCurry[T] = new InfCurry[T] { 
    def apply(x: T) = f(x) 
    } 
} 

С помощью этой небольшой утилиты вы можете определить такие вещи, как это:

val f: InfCurry[Int] = InfCurry { x => 
    println(x) 
    f 
} 

И вы это мало использовать вещь вот так:

val g = f(1)(2)(3)(4)(5)(6)(7) 
g(8)(9)(10)(11)(12) 

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

+1

Моя цель - сделать мой синтаксис более дружелюбным. У меня есть 2 много скобок здесь, и я не могу их удалить. , так что я не могу сделать: myFunc arg1 arg2 arg3 ..... –

+0

Могу я использовать неявное создание такого синтаксиса? если так как? –

+2

Боюсь, вы не можете получить этот синтаксис типа Haskell в Scala. Вы можете прочитать скобки только в этом специальном случае: http: // www.scala-lang.org/node/118. Но это не сработает в вашем случае, потому что 'myFunc arg1 arg2 arg3' будет интерпретироваться как' myFunc.arg1 (arg2) .arg3() ', что является чем-то совершенно другим. Кроме того, implicits не может помочь вам здесь. –

Смежные вопросы