2012-06-01 8 views
3

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

Дано:

//First family of stuff 
trait A { 
    def doA {} 
} 

trait B { 
    def doB {} 
} 

//Second family of stuff 
trait X { 
    def doX {} 
} 

trait Y { 
    def doY {} 
} 

можно комбинировать элементы из двух семей вместе в 4 вариантах:

var f = new A with X {} 
f.doA 
d.doX 

var g = new A with Y {} 
//... 

Великого. Проблема в том, что я хочу, чтобы каждая из функций (doA и т. Д.) Возвращала комбинацию двух типов, чтобы я мог объединять вещи вместе. По сути я хочу сделать: черта A { Защиту doThing = { новый А с ThingThatImMixedInWithLikeXOrY {} } }

Каждый процессор должен возвращать анонимный класс, который состоит из 1) известного типа с процессором 2) Тип, с которым он был смешан.

Мой первый удар был использовать дженерики, что-то вроде этого:

trait A { 
    this : {def makeWithT[TOther]} => 
    def doA = makeWithT[B] 
} 

trait B { 
    this : {def makeWithT[TOther]} => 
    def doB = makeWithT[A] 
} 

trait X { 
    this : {def makeWithS[TOther]} => 
    def doX = makeWithT[Y] 
} 

trait Y { 
    this : {def makeWithS[TOther]} => 
    def doY = makeWithT[Y] 
} 

class Foo[T, S] extends S with T { 
    def makeWithT[OtherT] = new T with OtherT 
    def makeWithS[OtherT] = new S with OtherT 
} 

var f = new Foo[A, X] 
f.doA.doB 
f.doX.doA 
f.doX.doY 
... 

Очевидно, я столкнулся с каталогом проблем:

  1. Я не могу сделать общий класс который простирается от параметров типа

  2. Я не могу создать экземпляр моего анонимного класса через общий параметр

  3. Я не могу определить возвращаемый тип функций в признаке, потому что я не знаю тип, пока он не смешался с чем-то.

Я немного нуб, когда дело доходит до Скале, и я чувствую, что я собираюсь об этом в совершенно неправильном направлении, и, может быть, я должен использовать implicits и шаблон CanBuildFrom. Любая помощь будет принята с благодарностью.

Приветствия

+2

Вы минимизировали проблему и сделали ее очень абстрактной. В некоторых случаях это может быть хорошо, но я думаю, что в этом конкретном случае было бы более полезно, если бы вы описали нам конкретную проблему и цель, которую вы хотите архивировать. Насколько я вижу, в этом вопросе вы описываете (сломанное) решение проблемы, которое мы еще не знаем.Если вы поделитесь им с нами, возможно, мы сможем найти другое/лучшее/рабочее решение проблемы, с которой вы в настоящее время сталкиваетесь ... – tenshi

+0

ОК, здесь. Я хочу иметь грамматику, чтобы я мог делать такие вещи, как dataSource.map (...). Filter (...) Где dataSource - это мой собственный поток. Проблема в том, что на нем есть другие операции, которые не являются преобразованиями, а скорее изменениями в том, как выполняются вычисления. Например, я могу захотеть сделать datasource.asParallel.filter (...). AsSequential. Это немного надуманный пример, но вы можете видеть, что у меня есть две группы операций. Возвращаемый тип asParallel должен быть чем-то, что предоставляет операцию asSequential. –

ответ

1

Наиболее известное решение для наращиваемых процессоров стекируемого черта

http://www.artima.com/scalazine/articles/stackable_trait_pattern.html

trait StackableRoot { 
    def StackablePass (x:Int) : x 
} 
trait StackableDouble extends StackableRoot { 
    def internalPass (x:Int) = 2*x 
    abstract override def StackablePass(x:Int) = super.StackablePass(internalPass(x)) 
} 
trait StackableIncrement extends StackableRoot { 
    def internalPass (x:Int) = x+1 
    abstract override def StackablePass(x:Int) = super.StackablePass(internalPass(x)) 
} 

есть некоторые шаблонные с

abstract override def StackablePass(x:Int) = super.StackablePass(internalPass(x)) 

, которые нельзя избежать, упаковка в параметризованный признак, так как это потребует e scala, чтобы наследовать некоторый признак с разными параметрами несколько раз, что запрещено известным стиранием типа.

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