Soy completamente nuevo para Haskell (y más generalmente para la programación funcional), así que perdóneme si esto es realmente algo básico. Para obtener más que un gusto, trato de implementar en Haskell algunas cosas algorítmicas en las que estoy trabajando. Tengo un módulo simple Interval
que implementa intervalos en la línea. Contiene el tipoHaskell novato en los tipos
data Interval t = Interval t t
la función auxiliar
makeInterval :: (Ord t) => t -> t -> Interval t
makeInterval l r | l <= r = Interval l r
| otherwise = error "bad interval"
y algunas funciones de utilidad sobre los intervalos.
Aquí, mi interés radica en los intervalos multidimensionales (intervalos d), aquellos objetos que se componen de d intervalos. Quiero considerar por separado los intervalos d que son la unión de d intervalos separados en la línea (intervalo múltiple) de aquellos que son la unión del intervalo d en d líneas separadas (intervalo de seguimiento). Con los tratamientos algorítmicos distintas en mente, creo que sería bueno tener dos tipos distintos (incluso si ambos son listas de intervalos aquí) como
import qualified Interval as I
-- Multilple interval
newtype MInterval t = MInterval [I.Interval t]
-- Track interval
newtype TInterval t = TInterval [I.Interval t]
para permitir comprobaciones de validez distintas, por ejemplo,
makeMInterval :: (Ord t) => [I.Interval t] -> MInterval t
makeMInterval is = if foldr (&&) True [I.precedes i i' | (i, i') <- zip is (tail is)]
then (MInterval is)
else error "bad multiple interval"
makeTInterval :: (Ord t) => [I.Interval t] -> TInterval t
makeTInterval = TInterval
¡Ahora llego al punto, por fin! Pero algunas funciones están naturalmente relacionadas con intervalos múltiples e intervalos de seguimiento. Por ejemplo, una función order
devolvería el número de intervalos en un intervalo múltiple o un intervalo de seguimiento. ¿Que puedo hacer? Añadiendo
-- Dimensional interval
data DInterval t = MIntervalStuff (MInterval t) | TIntervalStuff (TInterval t)
no ayuda mucho, ya que, si entiendo bien (corríjanme si me equivoco), que tendría que escribir
order :: DInterval t -> Int
order (MIntervalStuff (MInterval is)) = length is
order (TIntervalStuff (TInterval is)) = length is
y llame order
como order (MIntervalStuff is)
o order (TIntervalStuff is)
cuando is
es un MInterval
o un TInterval
. No es tan bueno, parece extraño. Tampoco quiero duplicar la función (tengo muchas funciones relacionadas con los intextuales múltiples y de seguimiento, y algunas otras definiciones de intervalo d, como la longitud igual múltiple y los intervalos de seguimiento).
Me da la sensación de que estoy completamente equivocado y me he perdido un punto importante acerca de los tipos en Haskell (y/o no puedo olvidarme lo suficiente sobre la programación de OO). Entonces, una pregunta bastante nueva, ¿cuál sería la mejor manera en Haskell para manejar una situación así? ¿Tengo que olvidarme de introducir MInterval
y TInterval
e ir solo con un tipo?
Gracias mucho por su ayuda,
Garulfo
Como un aparte, 'foldr (&&) verdadero == y'. – Nefrubyr