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
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.