[Haskell-cafe] Modifying a product type generically

Michael Orlitzky michael at orlitzky.com
Fri Jan 2 20:45:30 UTC 2015

On 01/02/2015 01:04 PM, Aleksey Khudyakov wrote:
>> with as little code as possible. In my real problem, Foo may have 30
>> fields, and BigFoo 31 -- if you know of a better way, stop me now.
> Please stop. Some time ago I wrote library exactly for working with
> product types: fixed-vector-hetero. Example code below. I think

Wow, thanks, this is almost exactly what I've been looking for. My next
trick was going to be to combine "convert", "cons", and "tail" operations.

>From your example, we can `cons` an "A" to a Foo to get a BigFoo:

  > H.cons "A" (Foo 1 2) :: BigFoo
  BigFoo "A" 1 2

And we can `tail` a BigFoo to get a Foo:

  > H.tail (BigFoo "Hello" 1 2) :: Foo
  Foo 1 2

But if I combine the two, GHC doesn't know what to do:

  > H.cons "A" (H.tail (BigFoo "Hello" 1 2)) :: BigFoo

      Couldn't match type ‘H.Elems v0’ with ‘'[Int, Int]’
      The type variable ‘v0’ is ambiguous
      Expected type: [Char] : H.Elems v0
        Actual type: H.Elems BigFoo
      In the expression:
        H.cons "A" (H.tail (BigFoo "Hello" 1 2)) :: BigFoo
      In an equation for ‘it’:
        it = H.cons "A" (H.tail (BigFoo "Hello" 1 2)) :: BigFoo

I can make it work in this case by supplying a type signature for the
intermediate `tail` expression -- but what if there is no such type? Can
I trick it into deducing any old type with the right shape? An
intermediate tuple would work, for example.

Thanks again.

More information about the Haskell-Cafe mailing list