tipos simbolos mundo listas infinitas hola funciones ejemplos datos comentarios haskell list existential-type

simbolos - listas infinitas haskell



Haskell cuenta el tipo de lista (2)

No puede definir ofList o filter esta manera porque confunden las verificaciones de nivel de tipo con los valores de tiempo de ejecución. En particular, en el tipo del resultado, CountedList na , el tipo n debe determinarse en el momento de la compilación. El deseo implícito es que n debe ser proporcional a la longitud de la lista que es el primer argumento. Pero eso claramente no se puede saber hasta el tiempo de ejecución.

Ahora, podría ser posible definir una clase de tipos, digamos Counted, y luego (con la extensión Haskell apropiada), definir estos como:

ofList :: [a] -> (forall n. (CountedListable CountedList n) => CountedList n a)

Pero le resultaría difícil hacer algo con tal resultado, ya que las únicas operaciones que CountedListable podría admitir serían la extracción del conteo. No podría, digamos, obtener el head de tal valor porque el encabezado no podría definirse para todas las instancias de CountedListable

Así que, solo por diversión, he estado jugando con un tipo CountedList en Haskell, usando números de Peano y constructores inteligentes .

La head y la tail seguras para los tipos me parecen realmente geniales.

Y creo que he llegado al límite de lo que sé hacer.

{-# LANGUAGE EmptyDataDecls #-} module CountedList ( Zero, Succ, CountedList, toList, ofList, empty, cons, uncons, head, tail, fmap, map, foldl, foldr, filter ) where import qualified List (foldr, foldl, filter) import Prelude hiding (map, head, foldl, foldr, tail, filter) data Zero data Succ n data CountedList n a = CL [a] toList :: CountedList n a -> [a] toList (CL as) = as ofList :: [a] -> CountedList n a ofList [] = empty ofList (a:as) = cons a $ ofList as empty :: CountedList Zero a empty = CL [] cons :: a -> CountedList n a -> CountedList (Succ n) a cons a = CL . (a:) . toList uncons :: CountedList (Succ n) a -> (a, CountedList n a) uncons (CL (a:as)) = (a, CL as) head :: CountedList (Succ n) a -> a head = fst . uncons tail :: CountedList (Succ n) a -> CountedList n a tail = snd . uncons instance Functor (CountedList n) where fmap f = CL . fmap f . toList map :: (a -> b) -> CountedList n a -> CountedList n b map = fmap foldl :: (a -> b -> a) -> a -> CountedList n b -> a foldl f a = List.foldl f a . toList foldr :: (a -> b -> b) -> b -> CountedList n a -> b foldr f b = List.foldr f b . toList filter :: (a -> Bool) -> CountedList n a -> CountedList m a filter p = ofList . List.filter p . toList

(perdón por los errores de transcripción: la máquina en la que escribí esto originalmente con mi compilador Haskell está inactiva).

La mayor parte de lo que he hecho compila sin un problema, pero tengo problemas con ofList y filter . Creo que entiendo por qué, cuando digo ofList :: [a] -> CountedList na , estoy diciendo ofList :: forall n . [a] -> CountedList na ofList :: forall n . [a] -> CountedList na : la lista creada puede ser de cualquier tipo de recuento deseado. Lo que quiero escribir es el equivalente del pseudo tipo ofList :: exists n . [a] -> CountedList na ofList :: exists n . [a] -> CountedList na , pero no sé cómo.

¿Hay alguna solución que me permita escribir funciones de ofList y filter como lo estoy imaginando, o he llegado al límite de lo que puedo hacer con esto? Tengo la sensación de que hay un truco con los tipos existenciales que me estoy perdiendo.


No puedes escribir

ofList :: [a] -> (exists n. CountedList n a) -- wrong

pero puedes escribir

withCountedList :: [a] -> (forall n. CountedList n a -> b) -> b

y ofList una función que represente lo que ofList hecho con el resultado de ofList , siempre que su tipo sea independiente de la longitud de la lista.

Por cierto, puedes asegurarte de que el tipo de una lista corresponda a su longitud en el sistema de tipos, y no confiar en los constructores inteligentes:

{-# LANGUAGE GADTs #-} data CountedList n a where Empty :: CountedList Zero a Cons :: a -> CountedList n a -> CountedList (Succ n) a