Vamos a ver lo que sucede cuando nos adaptamos GHC's Set code para dar cabida a los conjuntos infinitos:
module InfSet where
data InfSet a = Bin a (InfSet a) (InfSet a)
-- create an infinite set by unfolding a value
ofUnfold :: (x -> (x, a, x)) -> x -> InfSet a
ofUnfold f x =
let (lx,a,rx) = f x
l = ofUnfold f lx
r = ofUnfold f rx
in Bin a l r
-- check for membership in the infinite set
member :: Ord a => a -> InfSet a -> Bool
member x (Bin y l r) = case compare x y of
LT -> member x l
GT -> member x r
EQ -> True
-- construct an infinite set representing a range of numbers
range :: Fractional a => (a, a) -> InfSet a
range = ofUnfold $ \(lo,hi) ->
let mid = (hi+lo)/2
in ((lo, mid), mid, (mid, hi))
Nota cómo, en vez de construir el conjunto infinito de una lista infinita, Yo en cambio definir una función ofUnfold
a desplegarse un solo valor en una lista infinita. Nos permite construir ambas ramas perezosamente en paralelo (no necesitamos terminar una rama antes de construir otra).
Vamos a darle un giro:
ghci> :l InfSet
[1 of 1] Compiling InfSet (InfSet.hs, interpreted)
Ok, modules loaded: InfSet.
ghci> let r = range (0,128)
ghci> member 64 r
True
ghci> member 63 r
True
ghci> member 62 r
True
ghci> member (1/2) r
True
ghci> member (3/4) r
True
Bueno, que parece funcionar. ¿Qué pasa si probamos un valor fuera del conjunto?
ghci> member 129 r
^CInterrupted.
Eso solo se ejecutará y se ejecutará y nunca lo abandonará. No hay ramas de detención en el conjunto inifinite, , por lo que la búsqueda nunca se cierra. Podríamos comprobar el rango original de alguna manera, pero eso no es práctico para los conjuntos infinitos de elementos discretos:
ghci> let ex = ofUnfold (\f -> (f . (LT:), f [EQ], f . (GT:))) id
ghci> :t ex
ex :: InfSet [Ordering]
ghci> member [EQ] ex
True
ghci> member [LT,EQ] ex
True
ghci> member [EQ,LT] ex
^CInterrupted.
conjuntos infinitos Así son posibles pero no estoy seguro de que son útiles .
Puede ver en [fuente de Set.fromList] (http://hackage.haskell.org/packages/archive/containers/latest/doc/html/src/Data-Set.html#fromList) se implementa con 'foldlStrict'. (Por qué no usa 'foldl'' No estoy seguro, pero aparentemente es el mismo.) –