Type error in computation expression is too "big"
LightAndLight opened this issue · comments
Branch: https://github.com/LightAndLight/ipso/tree/issue/218
Program:
# bug.ipso
main : IO ()
main =
comp
bind string <- io.pure "hello"
if string then io.pure () else io.pure ()
Expected output:
bug.ipso:5:8: error: expected type "Bool", got type "String"
|
5 | if string then io.pure () else io.pure ()
| ^
Actual output:
bug.ipso:5:5: error: expected type "String -> IO ?6", got type "Bool -> IO ()"
|
5 | if string then io.pure () else io.pure ()
| ^
The computation expression is desugared to io.andThen (io.pure "hello") (\string -> if string then io.pure () else io.pure ())
. The lambda is inferred to have type Bool -> IO ()
.
When checking that \string -> if string then io.pure () else io.pure ()
has type String -> IO ?
, we need to push the argument type String
down so that string : String
while inferring if string then io.pure () else io.pure ()
.
Here is a prototype of how to "push" known types down in a unification-based type checker.