I have this code and it won't compile, highlighting the x and y right of Point3 and writing: "Multiple declarations of x" and "Multiple declarations of y". What's wrong? Can't Point2 and Point3 have the same member name?
data Point2 = Point2 {x :: Float, y :: Float}
data Point3 = Point3 {x :: Float, y :: Float, z :: Float}
No, this is not currently supported. The standard approach is to prefix each field with something unique to the particular datatype, e.g. p2x
, p2y
, p3x
etc.
The reason this isn't supported is that each record field name implicitly generates a "selector" function, e.g. x :: Point2 -> Float
. Having two fields with the same name in the same scope would generate a clash.
This is a long-standing bugbear for many people and will be addressed by the upcoming language extension OverloadedRecordFields
, which will hopefully be part of GHC 7.12 (due early 2016).
When enabled, this extension will allow the same field name to be used in multiple records. The field selector will have an overloaded type which will generally be resolved by type inference.