jimka
May 16, 2019, 3:19pm
#1
I have a call to foldLeft
, where the 2nd argument is a function (Bdd,Int)=>Bdd
,
but the first argument BddTrue
is an object defined as below.
bitsToSet(truthTable).map(_ - 1).foldLeft(BddTrue)((b1:Bdd,i2:Int) => And(b1,i2))
The compiler message I get is:
Error:(14, 78) type mismatch;
found : Bdd
required: BddTrue.type
bitsToSet(truthTable).map(_ - 1).foldLeft(BddTrue)((b1:Bdd,i2:Int) => And(b1,i2))
BddTrue
is defined as follows.
abstract class BddTerm extends Bdd {
...
}
object BddTrue extends BddTerm {
...
}
Is there some way for me to decorate the first argument of foldLeft
to make the compiler happy? Because yes indeed, BddTrue
is an object of type Bdd
curoli
May 16, 2019, 3:33pm
#2
bitsToSet(truthTable).map(_ - 1).foldLeft(BddTrue: Bdd)((b1:Bdd,i2:Int) => And(b1,i2))
1 Like
jimka
May 16, 2019, 3:53pm
#3
Great I was trying BddTrue[Bdd]
and BddTrue.asInstanceOf[Bdd]
Yeah, this isn’t an unusual problem. The compiler’s type inference is smart, but sometimes gets locked into an overly-specific type too early, so that the general type then fails later on. As shown by @curoli , the solution is usually to give the compiler a hint about the more general type that you intended in the first place.
jimka
May 16, 2019, 4:13pm
#5
I need to remember that syntax. The :
is normally used in a declaration, I wan’t aware it could be used in an evaluation position.
…alternatively: .foldLeft[Bdd](BddTrue)((b, i) => ...
1 Like
jimka
May 16, 2019, 4:35pm
#7
ahh foldLeft[Bdd]
, that was why I was remembering the square brackets.
To be clear, if you have an expression with a type ascription like expr: A
you are not casting. You are ascribing a more general type than what would be inferred, but it still must typecheck (unlike .asInstanceOf
which is unchecked and is therefore very dangerous).
1 Like
jimka
May 17, 2019, 6:23am
#9
great. so what’s the different between foldLeft[T](z)(...)
and foldLeft(z:T)(...)
? is it the same or is there some semantic difference as well?
The difference in how they arrive at the same result is mostly academic.
foldLeft[T](z)
fixes the type parameter of the foldLeft
to T
, which makes the expected type of z
into T
, which the typechecker checks.
foldLeft(z: T)
makes the expected type of z
be T
, which the typechecker checks, and infers the type parameter of foldLeft
should be T
too.
jimka
May 17, 2019, 12:27pm
#11
ah yes, and for foldLeft
it is the first argument who has type T
. accident of foldLeft
that the two are the same thing in the end.