Usted está buscando una lista heterogénea, que la mayoría no lo hacen Haskellers gusta particularmente a pesar de que ellos mismos han pedido esta misma pregunta cuando primero aprender Haskell.
escribe:
shapes :: (Shape t) => [t]
Esto dice la lista tiene el tipo t
, todos los cuales son los mismos y pasar a ser una forma (la misma forma!). En otras palabras, no, no debería funcionar como lo tienes.
Dos formas comunes para manejarlo (una forma Haskell 98 primero, y luego una manera más elegante que yo no recomiendo segundo) son:
Utilice un nuevo tipo de unión estáticamente los subtipos de interés:
data Foo = F deriving Show
data Bar = B deriving Show
data Contain = CFoo Foo | CBar Bar deriving Show
stuffExplicit :: [Contain]
stuffExplicit = [CFoo F, CBar B]
main = print stuffExplicit
Esto es bueno ya que es sencillo y no pierde ninguna información sobre lo que está en la lista. Puede determinar que el primer elemento es un Foo
y el segundo elemento es un Bar
. El inconveniente, como probablemente ya se haya dado cuenta, es que debe agregar explícitamente cada tipo de componente creando un nuevo constructor de tipo Contain
. Si esto no es deseable, sigue leyendo.
Usar tipos existenciales: Otra solución implica perder información sobre los elementos; solo conserva, por ejemplo, el conocimiento de que los elementos están en una clase particular. Como resultado, solo puede usar operaciones de esa clase en los elementos de la lista. Por ejemplo, el siguiente sólo se recordarán los elementos son de la clase Show
, por lo que la única cosa que puede hacer para los elementos es utilizar las funciones que son polimórficos en Show
:
data AnyShow = forall s. Show s => AS s
showIt (AS s) = show s
stuffAnyShow :: [AnyShow]
stuffAnyShow = [AS F, AS B]
main = print (map showIt stuffAnyShow)
Esto requiere algunas extensiones al lenguaje Haskell , es decir, ExplicitForAll
y ExistentialQuantification
. Tuvimos que definir showIt
explícitamente (usando la coincidencia de patrones para deconstruir el tipo AnyShow
) porque no puede usar nombres de campo para tipos de datos que usan cuantificación existencial.
Hay más soluciones (con suerte, otra respuesta usará Data.Dynamic
- si nadie lo hace y usted está interesado, entonces lea sobre él y no dude en publicar cualquier pregunta que la lectura genere).
http://www.haskell.org/haskellwiki/Heterogenous_collections –
Conocía colecciones heterogéneas, pero es algo que quería evitar. – Arlen