Haskell doesn't have dot notation for record members. For each record member a compiler creates a function with the same name with a type RecType -> FieldType. This leads to name conflicts. Are there any ways to work around this, i.e. how can I have several records with the same field names?
相关问题
- Understanding do notation for simple Reader monad:
- Making Custom Instances of PersistBackend
- Haskell: What is the differrence between `Num [a]
- applying a list to an entered function to check fo
- Haskell split a list into two by a pivot value
相关文章
- Is it possible to write pattern-matched functions
- Haskell underscore vs. explicit variable
- Top-level expression evaluation at compile time
- Stuck in the State Monad
- foldr vs foldr1 usage in Haskell
- List of checkboxes with digestive-functors
- How does this list comprehension over the inits of
- Replacing => in place of -> in function type signa
The GHC developers developed a couple of extensions to help with this issue . Check out this ghc wiki page. Initially a single
OverloadedRecordFields
extension was planned, but instead two extensions were developed. The extensions are OverloadedLabels and DuplicateRecordFields. Also see that reddit discussion.The DuplicateRecordFields extensions makes this code legal in a single module:
As of 2019, I'd say these two extensions didn't get the adoption I thought they would have (although they did get some adoption) and the status quo is probably still ongoing.
For large projects, I prefer to keep each type in its own module and use Haskell's module system to namespace accessors for each type.
For example, I might have some type
A
in moduleA
:... and another type
B
with similarly-named fields in moduleB
:Then if I want to use both types in some other module
C
I can import them qualified to distinguish which accessor I mean:Unfortunately, Haskell does not have a way to define multiple name-spaces within the same module, otherwise there would be no need to split each type in a separate module to do this.
Another way to avoid this problem is to use the lens package. It provides a makeFields template haskell function, which you can use like this:
If you don't want to use TemplateHaskell and lens, you can also do manually what lens automates using TemplateHaskell:
But I can really recommend learning lens, as it also provides lots of other utilities, like modifying or setting a field.