Use named TypedHoles
:
> let f x = _g . _h x $ x
Found hole ‘_g’ with type: b0 -> c
Where: ‘b0’ is an ambiguous type variable
‘c’ is a rigid type variable bound by
the inferred type of f :: s -> c at <interactive>:2:5
Relevant bindings include
x :: s (bound at <interactive>:2:7)
f :: s -> c (bound at <interactive>:2:5)
In the first argument of ‘(.)’, namely ‘_g’
In the expression: _g . _h x
In the expression: _g . _h x $ x
Found hole ‘_h’ with type: s -> s -> b0
Where: ‘b0’ is an ambiguous type variable
‘s’ is a rigid type variable bound by
the inferred type of f :: s -> c at <interactive>:2:5
Relevant bindings include
x :: s (bound at <interactive>:2:7)
f :: s -> c (bound at <interactive>:2:5)
In the expression: _h
In the second argument of ‘(.)’, namely ‘_h x’
In the expression: _g . _h x
So this gives you that _g :: b0 -> c
and _h :: s -> s -> b0
with the context of x :: s
and f :: s -> c
. The type-checker can infer these types most of the time (this is the point of TypedHoles
), and you can give them names. If you want, you can define all your functions with a _
as the first character of the symbol name, then later use your editor to replace _(.+)\b
with \1
. If you want to work around the lens convention of using _name
for a record field then just put 2 underscores on your hole name.
This will still keep your code from compiling though, but if you use this in combination with -fdefer-type-errors
they'll be reported as warnings instead, allowing your type errors to occur at runtime.
= undefined
for such functions... but, good question, I've also sometimes wanted that for ideas so weird I'm not sure it's worth trying to get them to type-check, since it might not even parse. - leftaroundaboutpointfree
and check for "Parse error: EOF", but this makes it difficult to do anything more than a single-line expression. - bheklilr