LightAndLight / ipso

A functional scripting language.
https://ipso.dev
17 stars 1 forks source link

Type error in computation expression is too "big" #218

Closed LightAndLight closed 1 year ago

LightAndLight commented 2 years ago

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 ()
  |     ^
LightAndLight commented 2 years ago

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 ().

LightAndLight commented 2 years ago

Here is a prototype of how to "push" known types down in a unification-based type checker.