[Haskell-beginners] How to "add column" to a Table?

Michael Orlitzky michael at orlitzky.com
Mon Apr 27 13:25:08 UTC 2015


On 04/27/2015 02:46 AM, martin wrote:
> 
> Aren't you adding a *row* to a Table which allows rows of multiple
> shapes? What I am looking for is an operation which adds a *column*
> to a regular table, i.e. one where all rows have the same shape.
> 

Oh, shit =)

Adding a column is a lot harder and does need some kind of "heterogenous
list" library. To do it without one, you need something like,

https://github.com/orlitzky/tuple/commit/8f6623b827f2192343c4fa4d520a4eb173033d9d

That has one advantage: you can understand what it's doing. But it's
not, uh, what's the word -- "aesthetically pleasing." My "prepend" is
basically your "addColumn," and you can see that the type is,

  prepend :: a -> b -> c

but that there's a functional dependency,

  a b -> c, b c -> a

which basically means that the output tuple's type is going to depend on
the input tuple's type and the type of the element that you're
prepending to it. You can make this work on a table, too:

  type Table a = [a]

  addColumn :: Prep a b c => a -> Table b -> Table c
  addColumn col = map (prepend col)

But if you know the type of the new (bigger) row at compile-time, what
you probably want instead is fixed-vector-hetero. Then you can write,

  import qualified Data.Vector.HFixed as H ( cons )
  ...
  addColumn col = map (H.cons col)

That will work for any HVector row type, but you need to either specify
or have the result type inferred. Otherwise you'll get an ambiguous type
error. So this won't work:

  ghci> let p1 = (1,"mjo",9000,True) :: Person
  ghci> let t1 = [p1] :: Table Person
  ghci> addColumn "new" t1

But this would,

  ghci> addColumn "new" t1 :: Table (String, Int, String, Int, Bool)
  [("new",1,"mjo",9000,True)]

If the result type can't be inferred, the tuple solution I mentioned
earlier might be less annoying, but switching "prepend" to "append" is
up to you!



More information about the Beginners mailing list