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.