LightAndLight / ipso

A functional scripting language.

Home Page:https://ipso.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.