I have a function literal
{case QualifiedType(preds, ty) =>
t.ty = ty ;
Some((emptyEqualityConstraintSet,preds)) }
>
Here is why I wanted to use a function literal and didn't like having to repeat the type twice. I was trying to build my own control construct to factor out all the option matching code. If there is too much overhead, then the control construct doesn't help any. Here is what I wanted to do
//This is the control construct definition
def switch[A,B]( x : Option[A], noneFun : =>B, someFun : A=>B) = x match {
case None => noneFun
case Some(y) => someFun(y) }
//And this is an example of using it.
def foobar( qt : Option[QualifiedType] ) =
switch( qt, {reportError("SNAFU");None},
{case QualifiedType(preds, ty) =>
Some((emptyEqualityConstraintSet,preds)) } )
The switch control construct compiles fine, but the usage caused an error because the SLS says that where I have an A, I should have a "definite type". That's because this kind of function literal (the kind with "case") is intended for partial functions where the argument could be legitimately any thing at all. I could argue my function literal with an int and that would not be a type error, but merely a matter of all the patterns failing. So the compiler needs some "top down" information to know what type I intend for the parameter of the "expanded function literal", i.e. what to put for X in the following
{(x : X) => x match {case Some(QualifiedType(preds, ty)) =>
Some((emptyEqualityConstraintSet,preds)) } }
I wonder why the compiler could't use the type of switch to see that I don't intend a partial function and then unify A with QualifiedType. But it doesn't.
Anyway it doesn't compile. But replacing A with Any eliminates the error. The following code actually compiles. What I lose is some type checking.
//This is the control construct definition
def switch[A,B]( x : Option[A], noneFun : =>B, someFun : A=>B) = x match {
case None => noneFun
case Some(y) => someFun(y) }
//And this is an example of using it.
def foobar( qt : Option[QualifiedType] ) =
switch( qt, {reportError("SNAFU");None},
{case QualifiedType(preds, ty) =>
Some((emptyEqualityConstraintSet,preds)) } )
I'd be interested to know (a) if the above definition of switch can be improved, and (b) if there is already a library function that does what I want.
Here is the final code. Yes, I think it is a fold (catamorphism).
def switch[A,B]( x : Option[A])(noneFun : =>B, someFun : A=>B) = x match {
case None => noneFun
case Some(y) => someFun(y) }
def foobar( qt : Option[QualifiedType] ) : Option[(EqualityConstraintSet, TypeRelationSet)] =
switch( qt )({reportError("SNAFU");None},
{case QualifiedType(preds, ty) =>
Some((emptyEqualityConstraintSet,preds)) } )
Thanks to Luigi.