3

Is it possible in Haskell to mix named and unnamed fields in records? Every example I see uses either all named or all unnamed fields like:

data A = A Int Int Int

or

data A = A {x::Int, y::Int, z::Int}

and I want something like

data A = A {_::Int, y::Int, z::Int)
Wojciech Danilo
  • 11,573
  • 17
  • 66
  • 132
  • Is there a particular situation you want this for? There might be some other way to do whatever you're trying to do. – Jeff Burka Aug 02 '13 at 00:22
  • @JeffBurka - I'm generating Haskell code and this feature would be very usefull for me. Right now I'm concidering using `Template Haskell` for this. – Wojciech Danilo Aug 02 '13 at 00:31
  • 1
    If the reason you don't want to name all of the fields is that you don't want to pollute the name space, here's a tip. As a general rule, I prefix a lowercase letter to all the field names in a record. In your example, I would write something like `data A = A {aX::Int, aY::Int, aZ::Int)`. Then I can still use `x`, `y` and `z` as names elsewhere in my code. – mhwombat Aug 02 '13 at 15:49
  • I have a related issue where I'd like to do this because I'm only using some of the record names and ghc is throwing warnings that the others are unused. Best way of getting around that? – MichaelJones Nov 19 '13 at 22:06
  • My bad, answered here: http://stackoverflow.com/questions/8221201 - you prefix the record name with '_' and ghc no longer warns about it. – MichaelJones Nov 19 '13 at 22:11

2 Answers2

2

If any field is named, then all of them must be named.

In case you didn't know, even if the fields are named, you don't have to use their names on every occasion. For example, if you have

data Point = Point {x, y :: Double}

then you can do

Point {x = 5, y = 7}

but you can still also do

Point 5 7

as if the fields were unnamed. Note, however, that record syntax allows you to specify just some fields, whereas if you use unnamed fields you must always specify them all.

MathematicalOrchid
  • 61,854
  • 19
  • 123
  • 220
1

Not sure if this is what you want, but you can always simulate record syntax by writing the get functions yourself.

data A = A Int Int Int

y :: A -> Int
y (A _ num _) = num

z :: A -> Int
z (A _ _ num) = num

It's uglier, but it has the same effect as mixing named and unnamed fields.

Jeff Burka
  • 2,571
  • 1
  • 17
  • 30
  • 1
    The same effect except for record syntax, which is a lot of the point of using a record in the first place. – shachaf Aug 02 '13 at 02:46