Reputation: 2911
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
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