I just wrote a fairly handy generator for making very simple vanilla case classes. It basically uses the apply method defined in the companion of them to make things pretty simple. I am not sure if something similar is in the library already.
basically you can just type in your specification.
implicit val arbPoint = ArbFunc(Point.apply _)
and then arbitrary points will be provided as needed
If I posted the code here i have feeling it would get severely mangled so I put it in a gist:
http://gist.github.com/440002
I think it is a simpler way to make the generators for case classes where you don't care that much about constraining the members of the case class.
posted to the mailing list, waiting for moderation.
Tuesday, June 15, 2010
Monday, June 14, 2010
Working around Dependent Method Types with Structural Types
Until dependent method types move out of experimental status in the scala compiler (they can be enabled with -Xexperimental) we have been using Structural Typing to work around their absence.
Here's how were doing it:
First, Given:
and an implementation:
We would like to write a function with given any AToB
returns the type of B specified by that A:
if we had dependent method types we could write this as
however this gives the error:
To work around this however and still preserve type safety we have been doing this:
Basically we are using a structural type to fix the abstract type B in AToB to a concrete
type BB. This will enforce the type constraint that we want. There is one annoyance that remains
however and I haven't figured out a solution for it yet, the compiler is inferring the wrong type
for BB.
gives the compiler error:
yuck, the work around is to say:
Which will compile correctly.
A few more examples which will not compile:
Here's how were doing it:
First, Given:
trait AToB {
type B
def b : B
}
and an implementation:
trait AToInt extends AToB {
final override type B = Int
}
object AToInt {
def apply(x : Int) = new AToInt {
final override val b = x
}
}
We would like to write a function with given any AToB
returns the type of B specified by that A:
if we had dependent method types we could write this as
def bOf[A <: AToB](a : A) : a.B = a.b
however this gives the error:
error: illegal dependent method type
def bOf[A <: AToB](a : A) : a.B = a.b
To work around this however and still preserve type safety we have been doing this:
def bOf[AA <: AToB {type B = BB}, BB](a : AA) : BB = a.b
Basically we are using a structural type to fix the abstract type B in AToB to a concrete
type BB. This will enforce the type constraint that we want. There is one annoyance that remains
however and I haven't figured out a solution for it yet, the compiler is inferring the wrong type
for BB.
val x : Int = bOf(AToInt(5))
gives the compiler error:
error: inferred type arguments [java.lang.Object with AToInt,Nothing] do not conform to method bOf's type parameter bounds [AA <: AToB{type B = BB},BB]
yuck, the work around is to say:
val x : Int = bOf[AToInt, AToInt#B](AToInt(5))
Which will compile correctly.
A few more examples which will not compile:
trait AToString extends AToB {
final override type B = String
}
object AToString {
def apply(x : String) = new AToString {
final override val b = x
}
}
//Will not compile
val x : String = bOf[AToInt, AToInt#B](AToInt(5))
//Will compile
val x : String = bOf[AToString, AToString#B](AToString("Good Times"))
//Will not compile
val x : Int = bOf[AToString, AToString#B](AToString("Good Times"))
Subscribe to:
Posts (Atom)