E06080: the constraining type with a generic/template cannot be a function
What went wrong
When constraining a generic type parameter, you must use a class, record, or trait - NOT a function type. Generic constraints exist to enable method access on T, and functions have no methods.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 647 (Why cannot I use a function type as a generic constraint?)
Rationale
Generic constraints enable calling methods on the parameterized type T. By constraining T to a class/trait, you can call methods defined on that constraining type. Functions only support () invocation - they have no methods to access, so constraining to a function is pointless.
How to fix it
- Define a class, record, or trait with the methods you need
- Constrain your generic to that type: 'of type T constrain by MyBaseClass'
- If you need function behavior, pass functions as parameters instead
Pass function as parameter
Where you wanted "any T that can be called", take the function as a parameter instead: a parameter typed 'Function of (String, Integer)' (or your own function type) can be called inside the method. The [EXAMPLE] section below shows a type parameter constrained by a function, then by a trait and by a component.
Common causes
- Wanting to constrain T to "anything callable" (use Function parameter instead)
- Confusing function types with class types
- Not realizing constraints are for method access
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E06080: the constraining type with a generic/template cannot be a function
#!ek9 defines module error.e06080.bad defines class //A type parameter can be constrained by a type, never by a function Checked of type T constrain by checkFunction default Checked() Checked() -> item as T require item? check() -> item as T <- rtn as Boolean: item? AlsoChecked of type T constrain by abstractCheck default AlsoChecked() AlsoChecked() -> item as T require item? check() -> item as T <- rtn as Boolean: item? defines function checkFunction() -> amount as Integer <- rtn as Boolean: amount? abstractCheck() as abstract -> amount as Integer <- rtn as Boolean?
Fixed: Constrain the type parameter by a trait, class or component instead
#!ek9 defines module error.e06080.good defines trait Checkable check() -> text as String <- rtn as Boolean: text? defines class ByTrait of type T constrain by Checkable default ByTrait() ByTrait() -> item as T require item? check() -> item as T <- rtn as Boolean: item? ByComponent of type T constrain by Checker default ByComponent() ByComponent() -> item as T require item? check() -> item as T <- rtn as Boolean: item? defines component Checker as open check() -> text as String <- rtn as Boolean: text?
Questions and answers
These Q&A entries show E06080 and its fix: