Lista de exhibibles: OOP supera a Haskell?

Quiero construir una lista de cosas diferentes que tienen una propiedad en común, a saber, que podrían convertirse en una cadena. El enfoque orientado a objetos es sencillo: definir interfazShowable y hacer que las clases de interés lo implementen. El segundo punto puede ser, en principio, un problema cuando no puede alterar las clases, pero supongamos que este no es el caso. Luego creas una lista deShowables y llénelo con objetos de estas clases sin ningún ruido adicional (por ejemplo, la conversión generalmente se realiza implícitamente). Prueba de concepto en Javase da aquí.

Mi pregunta es ¿qué opciones tengo para esto en Haskell? A continuación, analizo los enfoques que he probado y que realmente no me satisfacen.

Enfoque 1: existenciales. Funciona pero feo.

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

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

El principal inconveniente para mí aquí es la necesidad deSh Al llenar la lista. Esto se parece mucho a las operaciones upcast que se realizan implícitamente en lenguajes OO.

Más generalmente, el envoltorio ficticioShowable para lo que ya está en el idiomaShow type class: agrega ruido adicional en mi código. No es bueno.

Enfoque 2: impredicativos. Deseado pero no funciona.

El tipo más sencillo para una lista así para mí y lo que realmente deseo sería:

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

Aparte de eso (como escuché)ImpredicativeTypes es "frágil en el mejor de los casos y roto en el peor" no 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

y el mismo error para"abc". (Nota tipo firma para 1: sin ella recibo aún más mensaje extraño:Could not deduce (Num a) arising from the literal ‘1’)

Enfoque 3: Tipos de rango N junto con algún tipo de listas funcionales (¿listas de diferencias?).

En lugar de problemáticoImpredicativeTypes uno probablemente preferiría más estable y ampliamente aceptadoRankNTypes. Esto básicamente significa: mover deseadoforall a. Show a => a constructor fuera de tipo (es decir[]) a tipos de funciones simples. En consecuencia, necesitamos alguna representación de las listas como funciones simples. Como apenas escuché, hay tales representaciones. El que escuché son las listas de diferencias. Pero enDlist paquete el tipo principal es bueno viejodata entonces volvemos a los impredicativos. No investigé más esta línea ya que sospecho que podría producir un código más detallado que en el enfoque 1. Pero si cree que no lo hará, por favor, deme un ejemplo.

Línea de fondo: ¿cómo atacarías tal tarea en Haskell? ¿Podría dar una solución más sucinta que en el lenguaje OO (especialmente en lugar de llenar una lista; vea el comentario para el código en el enfoque 1)? ¿Puede comentar qué tan relevantes son los enfoques enumerados anteriormente?

UPD (basado en los primeros comentarios): la pregunta, por supuesto, se simplifica a efectos de legibilidad. El verdadero problema es más acerca de cómo almacenar cosas que comparten la misma clase de tipo, es decir, se pueden procesar más adelante de varias maneras (Show tiene solo un método, pero otras clases pueden tener más de uno). Esto factoriza soluciones que sugieren aplicarshow método justo al llenar una lista.

Respuestas a la pregunta(8)

Su respuesta a la pregunta