4

I am representing a table to store data as a Haskell record and I was wondering if there is a function to get the number of fields given a record?

I ask as I have a type class to represent a table and one of class functions is noOfCols; which correspond to the number of fields in a record representing a table.

data Price = Price {bid=[Float], ask=[Float]}

class Table a where
   noOfCols :: a -> Int
   ...

instance Table Price where
   noOfCols t = 2
   ...

So the problem is that I will be constantly adding new fields so it's possible to forget to update the instance implementation of noOfCols when I add new columns (fields) to Price; i.e. leaving it to 2 when I now have 3 or more fields.

Is there a function that can provide the number of fields for a given record so I don't have to make a manual edit everytime I change the record?

user3199023
  • 433
  • 2
  • 8

2 Answers2

4

This is something that can be solved via various generic programming libraries. For example:

{-# LANGUAGE DeriveDataTypeable #-}

import Data.Data

data Price = Price {bid :: [Float], ask :: [Float]}
  deriving (Typeable, Data)

noOfCols :: Data a => a -> Int
noOfCols = gmapQl (+) 0 (const 1)

Then:

GHCi> noOfCols (Price [1,2] [3,4,5])
2
GHCi> noOfCols (0,0,0,0)
4
kosmikus
  • 19,549
  • 3
  • 51
  • 66
2

Your noOfCols is the arity of the constructor function Price, i.e.

noOfCols = arity Price

See Haskell: Function to determine the arity of functions? for ways to implement arity (see the accepted answer). (Note: @kosmikus is IMHO a better solution for you).

Site note: Maybe [[Float]] is a better model for you, i.e.

type Price = [[Float]]

bid :: Price -> [Float]    
bid = (!! 0)

ask :: Price -> [Float]
ask = (!! 1)

noOfCols :: Price -> Int
noOfCols = length
Community
  • 1
  • 1
Stephan Kulla
  • 4,739
  • 3
  • 26
  • 35