Common Problems
- ToString is not defined on 'a'
- Records and Complex Instances
- Expected kind 'Bool or Effect' here, but kind 'Type' is used
ToString is not defined on 'a'
Given the program:
def main(): Unit \ IO =
let l = Nil;
println(l)
The Flix compiler reports:
❌ -- Type Error ---------------------
>> ToString is not defined on a. [...]
3 | println(l)
^^^^^^^^^^
missing ToString instance
The issue is that the empty list has the polymorphic type: List[a]
for any
a
. This means that Flix cannot select the appropriate ToString
trait
instance.
The solution is to specify the type of the empty list. For example, we can write:
def main(): Unit \ IO =
let l: List[Int32] = Nil;
println(l)
which solves the problem because Flix can find an instance of ToString
trait
for the concrete type List[Int32]
.
Records and Complex Instances
Given the program:
instance Eq[{fstName = String, lstName = String}]
The Flix compiler reports:
❌ -- Instance Error --------------------------------------------------
>> Complex instance type '{ fstName = String, lstName = String }' in 'Eq'.
1 | instance Eq[{fstName = String, lstName = String}]
^^
complex instance type
This is because, at least for the moment, it is not possible type define trait instances on records (or Datalog schema rows). This may change in the future. Until then, it is necessary to wrap the record in an algebraic data type. For example:
enum Person({fstName = String, lstName = String})
and then we can implement Eq
for the Person
type:
instance Eq[Person] {
pub def eq(x: Person, y: Person): Bool =
let Person(r1) = x;
let Person(r2) = y;
r1#fstName == r2#fstName and r1#lstName == r2#lstName
}
Expected kind 'Bool or Effect' here, but kind 'Type' is used
Given the program:
enum A[a, b, ef] {
case A(a -> b \ ef)
}
The Flix compiler reports:
❌ -- Kind Error -----------------------------------------------
>> Expected kind 'Bool or Effect' here, but kind 'Type' is used.
2 | case A(a -> b \ ef)
^^
unexpected kind.
Expected kind: Bool or Effect
Actual kind: Type
This is because Flix assumes every un-annotated type variable to have kind
Type
. However, in the above case a
and b
should have kind Type
, but ef
should have kind Bool
. We can make this explicit like so:
enum A[a: Type, b: Type, ef: Bool] {
case A(a -> b \ ef)
}