tipos Embalaje, como Int#
y funciones estrictas, como f (!x) = ...
, son algo diferente, pero no veo similitud conceptual - no permitir que thunks/pereza de alguna manera. Si Haskell era un lenguaje estricto como Ocaml, cada función sería estricta y cada tipo no incluido. ¿Cuál es la relación entre los tipos sin caja y la exigencia de rigor?¿Cuál es la relación entre los tipos sin caja y el rigor?
Respuesta
Sin Embalaje vs caja de Datos
Para apoyar parametric polymorphism y laziness, por defecto los tipos de datos de Haskell están representados de manera uniforme como un puntero a una closure en the heap, con una estructura como esta:
Estos son valores "encasillados". Un unboxed objeto está representada por el valor en sí directamente, sin ningún tipo de indirección o cierre. Int
está en caja, pero Int#
está desagrupado.
Lazy values requieren una representación en caja. Los valores estrictos no: pueden representarse como cierres totalmente evaluados en el montón, o como estructuras primitivas unboxed. Tenga en cuenta que pointer tagging es una optimización que podemos usar en objetos encuadrados, para codificar el constructor en el puntero al cierre.
la relación con rigurosidad
Normalmente, los valores unboxed se generan de manera ad hoc por los compiladores de lenguaje funcional. En Haskell, sin embargo, unboxed values son especiales.Ellos:
- tienen un tipo diferente,
#
; - solo se puede usar en lugares especiales; y
- están sin elevar, por lo que no se representan como un puntero a un valor de almacenamiento dinámico.
Debido a que no están elevados, son necesariamente estrictos. La representación de la pereza no es posible.
Así que los tipos de unboxed particulares, como Int#
, Double#
, realmente se representan como dobles o int en la máquina (en notación C).
Análisis Rigor
Por otra parte, GHC hace strictness analysis de tipos de Haskell regulares. Si el uso de un valor es estricto, es decir, nunca puede estar "indefinido", el optimizador puede reemplazar todos los usos del tipo normal (por ejemplo, Int
) con un contenedor (Int#
), ya que sabe que el uso de Int
es siempre estricto, y por lo tanto el reemplazo con el tipo más eficiente (y siempre estricto) Int#
es seguro.
Por supuesto, podemos tener estrictas tipos sin unboxed tipos, por ejemplo, un elemento-lista estricta polimórfica:
data List a = Empty | Cons !a (List a)
es estricta en sus elementos, pero no los representa como valores sin embalaje.
Esto también señala el error que cometió con respecto a los idiomas estrictos, like OCaml. Todavía necesitan compatibilidad con el polimorfismo, por lo que proporcionan una representación uniforme o se especializan en tipos de datos y funciones para todos los tipos. GHC usa de forma predeterminada una representación uniforme, al igual que OCaml, aunque GHC también puede usar specialize types and functions ahora (como plantillas C++).
Entonces, ¿hay algún uso de un tipo de caja estricta, como su ejemplo 'List'? ¿No tiene la misma representación que su contraparte perezosa? – haskelline
Tiene la misma representación, pero semántica diferente. Tales estructuras son a menudo útiles. –
Pero pensé, por ejemplo, 'data Pair = P Int Int' contendrá más indirecciones que' data Pair = P! Int! Int'. En el primero, ¿cada argumento es un puntero a un puntero (un thunk), y en este último es un puntero a un valor? – haskelline
tipos Unboxed son necesariamente estricta, pero no todos los valores estrictos son necesariamente sin embalaje.
data Foo a = Foo !a !a
tiene dos campos estrictas
data Bar a = Bar {-# UNPACK #-} !Int !a
tiene dos campos estrictas, pero el primero es sin embalaje.
En última instancia, los tipos razón sin embalaje son (necesariamente) estricta es que no hay lugar para almacenar el golpe seco, ya que son tontas, datos simple y llanamente en ese punto.
Argumentos de cualquier tipo se pueden hacer "estricta", pero los únicos tipos unboxed que han tipos en cajas correspondientes son Char#
, Int#
, Word#
, Double#
y Float#
.
Si conoces a lenguajes de bajo nivel como C, es más fácil de explicar. Los tipos no compartidos son como int
, double
, etc., y los tipos encuadrados son como int*
, double*
, etc. Cuando tiene un int
, ya conoce el valor completo tal como está representado en el patrón de bits, por lo tanto, no es perezoso. También debe ser estricto, ya que todos los valores de int
son válidos y no ⊥.
Sin embargo, dada una int*
puede optar por eliminar la referencia al puntero tarde para obtener el valor real (por lo tanto perezoso), y es posible tener punteros no válidos (que contiene ⊥, es decir, no estricto).
- 1. ¿Cuál es la relación entre las redes bayesianas y neuronales?
- 2. ¿Cuál es la relación entre "un" montón y "el" montón?
- 3. ¿Cuál es la relación entre el campo 'SYSTEM_PROPERTIES_MODE_ENVIRONMENT' y PropertyPlaceHolderConfigurer?
- 4. ¿Cuál es el objetivo de la declaración de rigor?
- 5. ¿Cuál es la relación entre Passenger y Capistrano?
- 6. ¿Cuál es la diferencia entre la relación Composición y Asociación?
- 7. Conversión eficiente entre vectores en caja y sin caja
- 8. ¿Cuál es la relación entre masksToBounds y cornerRadius?
- 9. ¿Cuál es la relación entre ContentPane y JPanel?
- 10. ¿Cuál es la relación entre docutils y Sphinx?
- 11. ¿Cuál es la relación entre entornos y proyectos en virtualenvwrapper?
- 12. ¿Cuál es la relación entre ghc-pkg y cabal?
- 13. ¿Cuál es la relación entre bitbucket.org y bytebucket.org?
- 14. ¿Cuál es la relación entre Xtext y ANTLR?
- 15. Cuál es la relación entre píxeles y píxeles escalados
- 16. ¿Cuál es la relación entre AppDelegate, RootViewController y UIApplication?
- 17. ¿Cuál es la relación entre OSGi y Dependency Injection
- 18. ¿Cuál es la relación entre WIC y GDI +?
- 19. nginx, ¿cuál es la relación entre worker_connections, keepalive_timeout y $ conexión
- 20. ¿Cuál es la relación entre UIView y CALayer
- 21. ¿Cuál es la relación entre GC, Finalize() y Dispose?
- 22. ¿Cuál es la diferencia/relación entre AVR y Arduino?
- 23. ¿Cuál es la relación entre __getattr__ y getattr?
- 24. ¿Cuál es la relación entre GTK, GTK + y GTK2?
- 25. ¿Cuál es la relación entre Selenium RC y WebDriver?
- 26. ¿Cuál es la relación entre la plantilla de C++ y la tipificación de pato?
- 27. ¿Cuál es la relación entre Iterable e Iterator?
- 28. ¿Cuál es la diferencia entre los tipos de datos y los literales en Java?
- 29. la función seq y rigor
- 30. ¿Cuál es la diferencia entre los tipos de datos brutos largos y largos en Oracle?
No tengo mucha experiencia con tipos no compartidos, por lo que incluso comentarios básicos son bienvenidos. – sdcvvc
No todos los tipos se desempaquetarán debido a polimorfismo. Las funciones polimórficas en OCaml y Haskell usan una representación uniforme de valores como cierres. Haskell permite la especialización, la generación de funciones personalizadas que utilizan argumentos unboxed (OCaml probablemente también lo haga). –