Dacto
Dacto

Reputation: 2911

DuplicateRecordFields and Function Composition

According to DuplicateRecordFields "we can use the type being pushed in to the occurrence of the selector, or a type signature on its argument, to determine the datatype that is meant".

So, the following works1:

{-# LANGUAGE DuplicateRecordFields #-}
module Records where

data A = A { x :: Bool }
data B = B { x :: Int }

f :: A -> Bool
f = x

But this doesn't:

{-# LANGUAGE DuplicateRecordFields #-}
module Records where

data A = A { x :: Bool }
data B = B { x :: Int }

f :: A -> Bool
f = not . x

{-
  duprecords.hs:9:11: error:
      Ambiguous occurrence `x'
      It could refer to either the field `x',
                               defined at duprecords.hs:6:14
                            or the field `x',
                               defined at duprecords.hs:5:14
-}

Why does this break when using a function with the record field? I thought it would still be disambiguated by the function type.

Upvotes: 2

Views: 327

Answers (1)

chi
chi

Reputation: 116174

I think the extension is too fragile, unfortunately.

From the docs:

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.

In f = not . x the type of the argument of x must be inferred, exploiting the type of (.) and of f (which is provided).

Disambiguating is cumbersome. One has to write

f = not . (x :: A -> Bool)

or, with PartialTypeSignatures on, (& silencing the warning)

f = not . (x :: A -> _)

Neither is convenient.

Upvotes: 3

Related Questions