简体   繁体   中英

Compiler can't infer type while using Newtype class Constraint purescript

I was trying to write a function that can get the data that a newtype wraps.

newtype Person = Person {name :: String, age :: Int}

getRecord :: forall r. Newtype Person r => Person -> r
getRecord (Person p) = p

This fails to compile and complains

Could not match type

    { age :: Int
    , name :: String
    }

  with type

    r0


while checking that type { age :: Int
                         , name :: String
                         }
  is at least as general as type r0
while checking that expression p
  has type r0
in value declaration getRecord

But when I do

getRecord :: forall r. Newtype Person r => Person -> r
getRecord  = unwrap 

It works fine !! My Question is why it can't infer the type the first time?

The newtype type class is defined like,

class (Coercible t a) <= Newtype t a | t -> a

which means it can infer the a when it knows what t is. Then why its not working the first time.

Constraint solving happens when calling the function, but not when defining one.

At call site, the compiler will solve the Newtype Person r constraint and figure out that r ~ { age :: Int, name :: String } , so you can use its fields.

But at definition site, the compiler doesn't do that. There, it's just some unknown type r . And since it's unknown, the compiler can't in good faith tell that r ~ { age :: Int, name :: String } , so there is a type mismatch.


Using unwrap works, because there the type r doesn't need to be known. Whatever it is, it's just passed straight to unwrap , and your function doesn't need to know anything about it.


Why does the compiler not do constraint solving at definition site? I mean it technically could, but that would be kinda useless anyway: after all, if you already know the type, just write it out:

getRecord :: Person -> { age :: Int, name :: String }
getRecord (Person p) = p

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM