2013-12-11 1 views
0

Я пытаюсь реализовать/переопределить функцию с пустым аргументом ввода с помощью частичной функции. Это лучше всего объяснить этим нерабочую минимальный пример:Scala Currying: функция переопределения с пустым аргументом частичной функцией

trait T 
trait TFactory { 
    def build(): T 
} 

class A(someParameter: Int) extends T 

object A extends TFactory { 
    def build(someParameter: Int)(): T = new A(someParameter) 
} 

Компилятор жалуется: object creation impossible, since method build in trait TFactory of type()T is not defined, что имеет смысл, поскольку тип сборки является (Int)()T. Моя следующая идея состояла в том, чтобы сделать тип build явно функцию с пустым аргументом и возвращает T, т.е .:

trait T 
trait TFactory { 
    def build:() => T // what about empty parenthesis after build? 
} 

class A(someParameter: Int) extends T 

object A extends TFactory { 
    def build(someParameter: Int): (() => T) = (() => new A(someParameter)) 
} 

Теперь очевидно, что тип build является () => T. К моему удивлению, компилятор теперь жалуется на object creation impossible, since method build in trait TFactory of type =>() => T is not defined (обратите внимание, что тип внезапно начинается с =>). Отчаянное добавление пустой скобки в конце определения функции не помогает.

Как я могу убедить мой компилятор, что эти типы на самом деле одинаковы?

Разъяснение:

Моя главная цель состоит в том, чтобы достичь параметров свободной инициализации T без необходимости завода для заводов. Пример:

val t = A(33).build()  // if this is possible, I though it might be possible to have: 
val t = A.build(33)() 

Вывод:

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

+0

Я не уверен, что я следую. TFactory обещает предоставить метод «build», который не принимает никаких параметров и возвращает либо T (в первом примере), либо функцию, возвращающую T (во втором). Но такой объект не определен в объекте A. –

+0

Предполагаемое поведение 'build' заключается в том, чтобы ничего не принимать в качестве входных данных и возвращать новый экземпляр' T'. Цель реализации в объекте A заключается в том, чтобы просто обернуть все необходимые параметры 'A', позволяющие инициализировать« без параметров ». – bluenote10

ответ

1

Я не совсем уверен, чего вы хотите достичь. Допустим, что ваш TFactory был дан, как и в первом примере:

trait T 

trait TFactory { 
    def build(): T 
} 

Тогда метод build, очевидно, не может принимать любой параметр. Если вы хотите настроить завод, вы можете иметь заводскую-завод:

class A(x: Int) extends T 

object A { 
    def apply(x: Int): TFactory = new TFactory { 
    def build() = new A(x) 
    } 
} 

val factory = A(33) 
val t = factory.build() 

Если определить TFactory просто быть функцией от () к T, вы можете использовать выделки

type TFactory =() => T 

object A { 
    def apply(x: Int)(): T = new A(x) 
} 

val factory: TFactory = A(33) _ 
val t = factory() 
+0

И не должно ли быть достигнуто точно так же, выполняя функцию 'build'? В конце концов, моя главная цель состояла в том, чтобы избежать FactoryFactory.Я надеялся добиться этой инициализации без параметров просто, возвращая функцию типа '() => T', которая кажется возможной, поскольку типы в примерах« почти правы ». – bluenote10

+0

Спасибо за предложение! Я думаю, что моя основная проблема с этим решением заключается в том, что я не могу гарантировать, что все, кто реализует 'T', также должны предоставить бесплатный способ создания экземпляра' T'. Моя первоначальная цель состояла в том, чтобы иметь 'val factory: TFactory' в' T', который бы ввел в действие эту ссылку (извините, что я не смог сделать это достаточно ясно). – bluenote10

+0

Для полноты: я задал новый вопрос [здесь] (http://stackoverflow.com/q/20542997/1804173), который посвящен большой картине за этим вопросом; Или, другими словами: этот вопрос здесь был просто полностью ошибочной попыткой придумать альтернативное решение этого другого вопроса. Я добавил соответствующий вывод выше и приму этот ответ, если никто не докажет, что мой вывод ошибочен. – bluenote10