¿Cuál es la diferencia cuando escribo esto?
data Book = Book Int Int
versus
newtype Book = Book (Int, Int) -- "Book Int Int" is syntactically invalid
haskell
types
type-systems
newtype
ewggwegw
fuente
fuente

newtype Book = Book Int Intno es válido. Sin embargo, puede tenernewtype Book = Book (Int, Int)lo señalado por dons a continuación.Respuestas:
Gran pregunta!
Hay varias diferencias clave.
Representación
newtypegarantiza que sus datos tendrán exactamente la misma representación en tiempo de ejecución, que el tipo que ajusta.datadeclara una nueva estructura de datos en tiempo de ejecución.Entonces, el punto clave aquí es que
newtypese garantiza que la construcción para el se borrará en el momento de la compilación.Ejemplos:
data Book = Book Int Intnewtype Book = Book (Int, Int)Observe cómo tiene exactamente la misma representación que a
(Int,Int), ya que elBookconstructor se borra.data Book = Book (Int, Int)Tiene un
Bookconstructor adicional no presente en elnewtype.data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!IntNo hay punteros! Los dos
Intcampos son campos de tamaño de palabra sin caja en elBookconstructor.Tipos de datos algebraicos
Debido a esta necesidad de borrar el constructor, a
newtypesolo funciona cuando se ajusta un tipo de datos con un solo constructor . No hay noción de nuevos tipos "algebraicos". Es decir, no puede escribir un equivalente de nuevo tipo de, digamos,ya que tiene más de un constructor. Tampoco puedes escribir
Rigor
El hecho de que el constructor se borre conduce a algunas diferencias muy sutiles en la rigidez entre
dataynewtype. En particular,dataintroduce un tipo que se "levanta", lo que significa, esencialmente, que tiene una forma adicional de evaluar a un valor inferior. Como no hay un constructor adicional en tiempo de ejecución connewtype, esta propiedad no se cumple.Ese puntero extra en el
Bookque(,)el constructor nos permite poner un valor inferior en.Como resultado,
newtypeydatatienen propiedades de rigidez ligeramente diferentes, como se explica en el artículo wiki de Haskell .Unboxing
No tiene sentido desempaquetar los componentes de a
newtype, ya que no hay constructor. Si bien es perfectamente razonable escribir:produciendo un objeto de tiempo de ejecución con un
Tconstructor y unInt#componente. Solo te desnudasIntconnewtype.referencias :
fuente
newtypese borra después de la compilación y el tiempo de ejecución usa la misma representación para los tipos antiguos y nuevos, ¿cómo podemos definir instancias para el tipo antiguo y el nuevo? ¿Cómo puede entender el tiempo de ejecución qué instancia usar?newtypeobviamente todavía no se borran.