2011-02-02 2 views
1

Итак, я хочу иметь кучу функций, которые получают состояние и возвращают результат с новым состоянием. По сути, государственная монада, но без монадических методов. В отличие от государственной монады, состояние не должно течь между функциями, а функция вызывается, возвращает результат и состояние, а состояние сохраняется до следующего вызова функции. Поэтому у меня есть список функций и список состояний (каждая функция имеет другой тип состояния), и я хочу вызвать каждую функцию с ее состоянием и обновить список состояний.Управление безопасным состоянием типа в функциях

Моя проблема в том, что я не могу заставить ее работать без кастинга.

Вот РЕПЛ сессия:

scala> type StateM[T] = T => (Int, T) 
defined type alias StateM 

scala> val c: StateM[Int] = {i => (i, i + 1)} 
c: (Int) => (Int, Int) = <function1> 

scala> val a: StateM[_] = c 
a: StateM[_] = <function1> 

scala> val z: Any = 0 
z: Any = 0 

scala> a(z) 
<console>:19: error: type mismatch; 
found : z.type (with underlying type Any) 
required: _$1 where type _$1 
     a(z) 
     ^

UPDATE: Я думал, что, возможно, экзистенциальные типы поможет. Что-то вроде:

scala> type StateT = Pair[StateM[X], X] forSome {type X} 
defined type alias StateT 

scala> val t: StateT = (c, 0) 
t: StateT = (<function1>,0) 

scala> t._1(t._2) 
<console>:13: error: type mismatch; 
found : t._2.type (with underlying type Any) 
required: X where type X 
     t._1(t._2) 
      ^
+1

Я смущен, почему можно было бы ожидать 'а (г)' для работы, которая эквивалентно 'c (0: Any)', что явно недействительно - вы не можете передать 'Any' функции, которая принимает' Int'. Не могли бы вы объяснить, что вы надеялись здесь? – Steve

+0

Я надеялся, что смогу сохранить функции, которые используют разные состояния на одной карте. Функция T в функции является типом состояния. – IttayD

ответ

0

Так что решение я нашел, чтобы использовать класс, который оборачивает два:

scala> case class StateWithVal[T](f: StateM[T], v: T) {def apply() = StateWithVal(f, f(v)._2)} 
defined class StateWithVal 

scala> val sv:StateWithVal[_] = StateWithVal(c, 0) 
sv: StateWithVal[_] = StateWithVal(<function1>,0) 

scala> sv() 
res15: StateWithVal[_] = StateWithVal(<function1>,1)