Why can't GHC infer record fields?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Why can't GHC infer record fields?

Clinton Mead

I asked this below question on Stack Overflow and I got an answer suggesting that GHC doesn't support type inference of overloaded record fields. But I'm wondering why this is the case.

Consider the following:

{-# LANGUAGE DuplicateRecordFields #-}

data A = A { name :: String }

data B = B { name :: String }

main = print $ name (A "Alice")

When compiled, I get the following message (on GHC 8.0.2)

duplicatedrecords.hs:7:16: error:
    Ambiguous occurrence name
    It could refer to either the field name’,
                             defined at duplicatedrecords.hs:5:14
                          or the field name’, defined at duplicatedrecords.hs:3:14

But if I modify the main line as follows:

main = print $ name ((A "Alice") :: A)

Compilation proceeds successfully. I'm not sure why I need the :: A here, it seems to be clear that (A "Alice") is of type A due to the A constructor.

It's worth noting that the following compiles fine:

data A = A { a_name :: String }
data B = B { b_name :: String }

class Name t where
  name :: t -> String

instance Name A where name = a_name
instance Name B where name = b_name

main = print $ name (A "Alice")

We can even go further as follows, allowing different result types:

{-# LANGUAGE TypeFamilies #-}

data A = A { a_name :: String }
data B = B { b_name :: Int }

class Name t where
  type family T t
  name :: t -> T t

instance Name A where
  type T A = String
  name = a_name

instance Name B where
  type T B = Int
  name = b_name

main = print $ name (A "Alice")

It seems like GHC just has to mechanically add a class for each unique record name and an instance for each record in each data type. This will mean however that name x == name y not implying that the types of x and y are the same but I'd expect that when using this extension anyway.

Just wondering if there's anything tricky I'm missing here regarding the implementation or that it just needs someone to implement it?


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: Why can't GHC infer record fields?

Matthew Pickering
Seems related to https://ghc.haskell.org/trac/ghc/ticket/11343

Matt

On Fri, Jun 23, 2017 at 10:43 AM, Clinton Mead <[hidden email]> wrote:

> I asked this below question on Stack Overflow and I got an answer suggesting
> that GHC doesn't support type inference of overloaded record fields. But I'm
> wondering why this is the case.
>
> Consider the following:
>
> {-# LANGUAGE DuplicateRecordFields #-}
>
> data A = A { name :: String }
>
> data B = B { name :: String }
>
> main = print $ name (A "Alice")
>
> When compiled, I get the following message (on GHC 8.0.2)
>
> duplicatedrecords.hs:7:16: error:
>     Ambiguous occurrence ‘name’
>     It could refer to either the field ‘name’,
>                              defined at duplicatedrecords.hs:5:14
>                           or the field ‘name’, defined at
> duplicatedrecords.hs:3:14
>
> But if I modify the main line as follows:
>
> main = print $ name ((A "Alice") :: A)
>
> Compilation proceeds successfully. I'm not sure why I need the :: A here, it
> seems to be clear that (A "Alice") is of type A due to the A constructor.
>
> It's worth noting that the following compiles fine:
>
> data A = A { a_name :: String }
> data B = B { b_name :: String }
>
> class Name t where
>   name :: t -> String
>
> instance Name A where name = a_name
> instance Name B where name = b_name
>
> main = print $ name (A "Alice")
>
> We can even go further as follows, allowing different result types:
>
> {-# LANGUAGE TypeFamilies #-}
>
> data A = A { a_name :: String }
> data B = B { b_name :: Int }
>
> class Name t where
>   type family T t
>   name :: t -> T t
>
> instance Name A where
>   type T A = String
>   name = a_name
>
> instance Name B where
>   type T B = Int
>   name = b_name
>
> main = print $ name (A "Alice")
>
> It seems like GHC just has to mechanically add a class for each unique
> record name and an instance for each record in each data type. This will
> mean however that name x == name y not implying that the types of x and y
> are the same but I'd expect that when using this extension anyway.
>
> Just wondering if there's anything tricky I'm missing here regarding the
> implementation or that it just needs someone to implement it?
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.