Lista de apresentações: OOP vence Haskell?

Quero criar uma lista de coisas diferentes que têm uma propriedade em comum, ou seja, elas podem ser transformadas em string. A abordagem orientada a objetos é direta: define interfaceShowable e fazer com que as classes de interesse o implementem. O segundo ponto pode, em princípio, ser um problema quando você não pode alterar as classes, mas vamos fingir que esse não é o caso. Então você cria uma lista deShowables e preencha-o com objetos dessas classes sem nenhum ruído adicional (por exemplo, upcasting geralmente é feito implicitamente). Prova de conceito em Javaé dado aqui.

Minha pergunta é quais opções para isso eu tenho em Haskell? Abaixo, discuto abordagens que tentei e que realmente não me satisfazem.

Abordagem 1: existenciais. Funciona mas feio.

{-# LANGUAGE ExistentialQuantification #-}
data Showable = forall a. Show a => Sh a

aList :: [Showable]
aList = [Sh (1 :: Int), Sh "abc"]

A principal desvantagem para mim aqui é a necessidade deSh ao preencher a lista. Isso se assemelha bastante às operações upcast que são implicitamente feitas em idiomas OO.

Em geral, o invólucro fictícioShowable para a coisa que já está no idioma -Show type class - adiciona ruído extra ao meu código. Nada de bom.

Abordagem 2: impredicativos. Desejado, mas não funciona.

O tipo mais direto para essa lista para mim e o que eu realmente desejo seria:

{-# LANGUAGE ImpredicativeTypes #-}
aList :: [forall a. Show a => a]
aList = [(1 :: Int), "abc"]

Além disso (como eu ouvi)ImpredicativeTypes é "frágil na melhor das hipóteses e quebrado na pior das hipóteses", não compila:

Couldn't match expected type ‘a’ with actual type ‘Int’
  ‘a’ is a rigid type variable bound by
      a type expected by the context: Show a => a

e o mesmo erro para"abc". (Observe a assinatura do tipo 1: sem ela, recebo uma mensagem ainda mais estranha:Could not deduce (Num a) arising from the literal ‘1’)

Abordagem 3: Tipos Rank-N, juntamente com algum tipo de lista funcional (listas de diferenças?).

Em vez de problemáticoImpredicativeTypes alguém provavelmente preferiria mais estável e amplamente aceitoRankNTypes. Isso basicamente significa: mover desejadoforall a. Show a => a construtor fora do tipo (ou seja,[]) para tipos de funções simples. Consequentemente, precisamos de alguma representação de listas como funções simples. Como eu mal ouvi, existem tais representações. O que ouvi falar são de listas de diferenças. Mas emDlist pacote o tipo principal é bom e velhodata então voltamos aos impredicativos. Não investiguei mais essa linha, pois suspeito que ela poderia produzir um código mais detalhado do que na abordagem 1. Mas se você acha que não, por favor, dê-me um exemplo.

Bottom line: como você atacaria essa tarefa em Haskell? Você poderia dar uma solução mais sucinta do que na linguagem OO (especialmente no lugar de preencher uma lista - veja o comentário do código na abordagem 1)? Você pode comentar o quão relevantes são as abordagens listadas acima?

UPD (com base nos primeiros comentários): a questão é obviamente simplificada com o objetivo de facilitar a leitura. O problema real é mais sobre como armazenar coisas que compartilham a mesma classe de tipo, ou seja, podem ser processadas posteriormente de várias maneiras (Show possui apenas um método, mas outras classes podem ter mais de um). Isso fatores soluções sugerem aplicarshow método certo ao preencher uma lista.

questionAnswers(8)

yourAnswerToTheQuestion