2010-07-25 9 views
16

Estoy cambiando algunos códigos de Haskell para que no utilicen listas para los conjuntos. Entiendo todo lo que se requiere, creo, pero no estoy seguro de cómo coincidir con los patrones. Las listas tienen esta bonita sintaxis literal que parece difícil de emular con el constructor Set. Por ejemplo, podría tener algo de código como este:Haskell Coincidencia de patrones en el conjunto vacío

foo [] = [] 
foo x = other_thing 

¿Cómo puedo escribir este código por lo que utiliza conjuntos en lugar de las listas?

Respuesta

30

Bueno, no se puede.

Set es un abstracto tipo de datos[0] que oculta deliberadamente su representación interna, principalmente para mantener invariantes de la estructura de datos que no se pueden cumplir de forma estática por el sistema de tipos (en concreto, la biblioteca estándar Data.Set.Set es un árbol de búsqueda binario).

Perder la capacidad de coincidencia de patrones en un tipo de datos abstracto es un poco desagradable de daño colateral, pero bueno. Sus opciones son aproximadamente:

  • Utilice predicados y guardias booleanos, p. null, como en la respuesta de trinithis.
  • Convierta el Set en una lista. La mayoría de las veces esto es una tontería, pero si quieres repetir el conjunto de todos modos, funciona bastante bien.
  • Habilita GHC's ViewPatterns extension, que proporciona azúcar sintáctico para usar funciones de acceso donde normalmente se aplica una coincidencia de patrón.
  • Evite hacer este tipo de comprobaciones en primer lugar; si tiene un Set, trátelo como un conjunto , y trabaje con él como un todo para mapear, filtrar, etc. No siempre es posible, pero puede conducir a un código más limpio con menos condicionales/iteraciones explícitas.

Ver patrones dejarían de escribir algo que se parece a esto:

foo (setView -> EmptySet) = [] 
foo (setView -> NonEmpty set) = other_thing 

... donde setView es una función que escribe. No hay mucho de un aumento de aquí, pero puede ser agradable para más pseudo-patrones complejos

Para evitar los controles explícitos, operaciones de conjuntos, además de bien conocidos, tales como union y intersection, considerar el uso de la filter, partition, map, y fold funciona en Data.Set.

[0]: Consulte this paper (advertencia: PDF) para la definición del término como lo estoy usando.

+0

+1 para la referencia de ViewPatterns! – ShiDoiSi

29
import qualified Data.Set as Set 

foo set 
    | Set.null set = bar 
    | otherwise = baz 
+1

+1 por respuesta simple –

+7

@simonjpascoe: Espera, podemos dar * respuestas * simples? Y aquí todo este tiempo pensé que había un mínimo de tres párrafos ... –

Cuestiones relacionadas