Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Silly duplicated record fields error

Tags:

haskell

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.

Why is this? The type signature :: A seems redundant to me, as surely the A constructor makes it clear to the compiler that (A "Alice") is of type A. But for some reason it makes a difference. Why is this and is there a way I can get this to compile without littering extra type signatures everywhere?

Note:

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 do it?

like image 840
Clinton Avatar asked Jun 23 '17 06:06

Clinton


1 Answers

-XDuplicateRecordFields currently doesn't infer types from arguments.

See GHC user guide section about this extension.

However, we do not infer the type of the argument to determine the datatype, or have any way of deferring the choice to the constraint solver. Thus the following is ambiguous:

But things are improving. So we might expect and finally get desired behavior:

https://prime.haskell.org/wiki/TypeDirectedNameResolution

like image 83
Shersh Avatar answered Oct 21 '22 12:10

Shersh