This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Recursive Type declaration

4 replies
Detering Dirk
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.

Hello all,

am I right, that recursive type declaration is
not possible in Scala 2.7 ?

Will it be in 2.8 ?

E.g.:

type S = PartialFunction[A, S]

How would one currently solve the problem
of a set of functions of a given type with
each returning a function of same type?

Concrete example:

var current = funcA
def handle(x) { current = current(x) }

val funcA = {
case ... => funcA
case ... => funcB
}

val funcB = {
case ... => funcA
case ... => funcC
}

val funcC = // you will know the principle

KR
Det

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Recursive Type declaration
abstract class S[A] extends PartialFunction[A, S[A]]

On Mon, Jul 13, 2009 at 5:47 AM, Detering Dirk <Dirk [dot] Detering [at] bitmarck [dot] de> wrote:
Hello all,

am I right, that recursive type declaration is
not possible in Scala 2.7 ?

Will it be in 2.8 ?

E.g.:

type  S = PartialFunction[A, S]

How would one currently solve the problem
of a set of functions of a given type with
each returning a function of same type?

Concrete example:

var current = funcA
def handle(x) { current = current(x) }

val funcA = {
    case ... =>  funcA
    case ... =>  funcB
}

val funcB = {
   case ... => funcA
   case ... => funcC
}

val funcC = // you will know the principle

KR
Det




--
***********************************************************************

Die Information in dieser E-Mail ist vertraulich und ist ausschliesslich
fuer den/die benannten Adressaten bestimmt. Ein Zugriff auf diese
E-Mail durch andere Personen als den/die benannten Adressaten ist
nicht gestattet. Sollten Sie nicht der benannte Adressat sein, loeschen
Sie bitte diese E-Mail.

***********************************************************************


BITMARCK SOFTWARE GMBH
Paul-Klinger-Strasse 15, 45127 Essen

Amtsgericht Essen HRB 20680
Geschaeftsfuehrer: Frank Krause



--
Daniel C. Sobral

Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: Recursive Type declaration

On Mon, Jul 13, 2009 at 4:05 PM, Daniel Sobral wrote:
> abstract class S[A] extends PartialFunction[A, S[A]]

That helps, but the tricky part of the original problem is dealing
with the recursive _values_ (which, because they're recursive, have to
be given explicit types).

The best I can come up with involves an additional wrapper for each
partial function,

trait RPF[T] extends PartialFunction[T, RPF[T]]

def rpf[T](pf : PartialFunction[T, RPF[T]]) = new RPF[T] {
def apply(t : T) = pf(t)
def isDefinedAt(t : T) = pf.isDefinedAt(t)
}

val funcA : RPF[Int] = rpf { // Type annotation is essential
case 1 => funcB
case 2 => funcC
case 3 => funcA
}

val funcB : RPF[Int] = rpf {
case 1 => funcC
case 2 => funcB
case 3 => funcA
}

val funcC : RPF[Int] = rpf {
case 1 => funcA
case 2 => funcB
case 3 => funcC
}

funcA(1)(2)(3)(1)(3)(1)

I'd be interested to know if there's anything more direct.

Cheers,

Miles

Detering Dirk
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
RE: Recursive Type declaration

Miles,

> The best I can come up with involves an additional wrapper
> for each partial function,
[...]

Thank you, that comes very close to my orignal idea,
and some smart renaming masks the wrapping process,
so no real need for a more direct way.

I played a bit with it and got a nice FSM script.

Next will be to hide the common things into a trait
and make the specific state definition and handling
a class implementation.

===================================================================
//---- the common things

trait StateFunc[T] extends PartialFunction[T, StateFunc[T]]

abstract class Event

type State = StateFunc[Event]

def transitions[T](pf: PartialFunction[T, StateFunc[T]]) = new
StateFunc[T] {
def apply(evt: T) = pf(evt)
def isDefinedAt(evt: T) = pf.isDefinedAt(evt)
}

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Recursive Type declaration
I like this! :-)

On Tue, Jul 14, 2009 at 10:38 AM, Detering Dirk <Dirk [dot] Detering [at] bitmarck [dot] de> wrote:
Miles,

> The best I can come up with involves an additional wrapper
> for each partial function,
[...]

Thank you, that comes very close to my orignal idea,
and some smart renaming masks the wrapping process,
so no real need for a more direct way.

I played a bit with it and got a nice FSM script.

Next will be to hide the common things into a trait
and make the specific state definition and handling
a class implementation.

===================================================================
//---- the common things

trait StateFunc[T] extends PartialFunction[T, StateFunc[T]]

abstract class Event

type State = StateFunc[Event]


def transitions[T](pf: PartialFunction[T, StateFunc[T]]) = new
StateFunc[T] {
   def apply(evt: T) = pf(evt)
   def isDefinedAt(evt: T) = pf.isDefinedAt(evt)
}


//--- the specific controller

case class StartEvent()  extends Event
case class MiddleEvent(amt:Int) extends Event
case class EndEvent()    extends Event



val stateA:State  = transitions {
         case e:StartEvent  => println("Received in A: "+e+" going to
B"); stateB
         case e:MiddleEvent => println("Received in A: "+e+" going to
C"); stateC
         case e:EndEvent    => println("Received in A: "+e+" going to
A"); stateA
   }

val stateB:State = transitions {
         case e:StartEvent  => println("Received in B: "+e+" going to
C"); stateC
         case e @ MiddleEvent(a) if (a > 5)  => println("Received in B:
"+e+" going to B"); stateB
         case e @ MiddleEvent(a) if (a <= 5) => println("Received in B:
"+e+" going to A"); stateA
         case e:EndEvent    => println("Received in B: "+e+" going to
A"); stateA
   }

val stateC:State = transitions {
         case e:StartEvent  => println("Received in C: "+e+" going to
A"); stateA
         case e:MiddleEvent => println("Received in C: "+e+" going to
B"); stateB
         case e:EndEvent    => println("Received in C: "+e+" going to
C"); stateC
   }


//--- run it (order of events doesn't make sense)

stateA(StartEvent()) (MiddleEvent(7)) (MiddleEvent(3)) (EndEvent())
(MiddleEvent(0)) (EndEvent()) (StartEvent())

===================================================================



--
Daniel C. Sobral

Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland