[Haskell-cafe] mapTuple

Marco Túlio Gontijo e Silva malebria at riseup.net
Thu Jan 11 11:50:58 EST 2007


Em Qui, 2007-01-11 às 16:51 +0100, minh thu escreveu: 
> 2007/1/11, Marco Túlio Gontijo e Silva <malebria at riseup.net>:
> > Em Qui, 2007-01-11 às 16:14 +0100, minh thu escreveu:
> > > you might want invistigate "heterogeneous lists" : in your case, it's
> > > "heterogeneous typle".
> >
> > But aren't tuples always heterogeneous?
> >
> You're right but the fact you apply a function on both element of the
> tuple constrains them to have the same type. Thus the problem is
> reminiscent of heterogeneous lists:
> how can you make (i.e. wrap) two values of different type so they have
> (after being wrapped) the same type ?
> 
> I couldnt find the page I was refering but found this one:
> http://en.wikibooks.org/wiki/Haskell/Existentially_quantified_types
> Look at the part on heterogeneous list, the examples are the thing you
> want (but for a list, not for a tuple).
> 
> Oh two things: 1/ I'm a bad haskell programmers since I have not
> enough experience (so maybe I'm throwing you in the bad direction but
> I prefer to answer so you not have to wait to long...); 2/ It's a bit
> of a habit here to answer with quite involved material even when a
> noob asks something (which I don't know if you are or not). Thus maybe
> the real answer to your question is wether what you ask for is really
> the root of the problem (I can't answer for you).
> 
> Another way to do what you want if you just want to use the 'show'
> function above on some types (and not every instance of Show) is to
> wrap each type individually in a variant type something like this:
> data MyShowable = S String | B Bool
> myShow :: MyShowable -> String
> 
> Optionnaly you can then make MyShowable an instance of Show.
> This way is much more 'basic level' haskell than the wiki page above.

Thanks for your answers.

I found the page of heterogeneous collections in haskell wiki:

http://haskell.org/haskellwiki/Heterogenous_collections

But my point was trying to do this without having to convert it to a
homogeneous tuple by using Dynamic.

I read a little of the wiki page, and it gave me some ideas:

(with ghci -fglasgow-exts)
let mapTuple :: forall c d e f. (forall a b. a -> b) -> (c, d) -> (e,
f); mapTuple f (x, y) = (f x, f y)

works fine, but when I run:

Prelude> mapTuple show ("string", True)

<interactive>:1:9:
    Couldn't match expected type `b' (a rigid variable)
           against inferred type `String'
      `b' is bound by the polymorphic type `forall a b. a -> b'
            at <interactive>:1:0-29
    In the first argument of `mapTuple', namely `show'
    In the expression: mapTuple show ("string", True)
    In the definition of `it': it = mapTuple show ("string", True)
Prelude>

And:

Prelude> mapTuple head (["string"], [True])

<interactive>:1:9:
    Couldn't match expected type `a' (a rigid variable)
           against inferred type `[a1]'
      `a' is bound by the polymorphic type `forall a b. a -> b'
            at <interactive>:1:0-33
      Expected type: a -> b
      Inferred type: [a1] -> a1
    In the first argument of `mapTuple', namely `head'
    In the expression: mapTuple head (["string"], [True])
Prelude>

This seemed to "work":

Prelude> mapTuple (const undefined) ("string", True)
(*** Exception: Prelude.undefined
Prelude>

The problem is it only works with forall a b. a -> b functions. I tried
with exits, but I got an error:

Prelude> let mapTuple :: forall c d e f. (exists a b. a -> b) -> (c, d)
-> (e, f); mapTuple f (x, y) = (f x, f y)
<interactive>:1:43: parse error on input `.'
Prelude>

Thanks for any help.

-- 
malebria
Marco Túlio Gontijo e Silva
Correio (MSN): malebria at riseup.net
Jabber (GTalk): malebria at jabber.org
Telefone: 33346720
Celular: 98116720
Endereço:
  Rua Paula Cândido, 257/201
  Gutierrez 30430-260
  Belo Horizonte/MG Brasil



More information about the Haskell-Cafe mailing list