
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
<interactive>:15:1: 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.