Ótima pergunta!
Existem várias diferenças importantes.
Representação
- A
newtype
garante que seus dados tenham exatamente a mesma representação em tempo de execução, como o tipo que você agrupa.
- Enquanto
data
declara uma nova estrutura de dados em tempo de execução.
Portanto, o ponto principal aqui é que a construção para o newtype
é garantida para ser apagada no tempo de compilação.
Exemplos:
newtype Book = Book (Int, Int)
Observe como ele tem exatamente a mesma representação que um (Int,Int)
, já que o Book
construtor é apagado.
data Book = Book (Int, Int)
Tem um Book
construtor adicional não presente no arquivo newtype
.
data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int
Sem ponteiros! Os dois Int
campos são campos com tamanho de palavra sem caixa no Book
construtor.
Tipos de dados algébricos
Devido a essa necessidade de apagar o construtor, newtype
só funciona ao agrupar um tipo de dados com um único construtor . Não há noção de novos tipos "algébricos". Ou seja, você não pode escrever um novo tipo equivalente a, digamos,
data Maybe a = Nothing
| Just a
já que possui mais de um construtor. Nem você pode escrever
newtype Book = Book Int Int
Rigor
O fato de o construtor ser apagado leva a algumas diferenças muito sutis no rigor entre data
e newtype
. Em particular, data
introduz um tipo que é "elevado", significando, essencialmente, que ele tem uma maneira adicional de avaliar o valor mais baixo. Como não há construtor adicional em tempo de execução newtype
, essa propriedade não é válida.
Esse ponteiro extra no Book
para (,)
construtor nos permite colocar um valor inferior em.
Como resultado, newtype
e data
possui propriedades de rigidez ligeiramente diferentes, conforme explicado no artigo da wiki Haskell .
Desembalagem
Não faz sentido desmarcar os componentes de a newtype
, pois não há construtor. Embora seja perfeitamente razoável escrever:
data T = T {-# UNPACK #-}!Int
produzindo um objeto de tempo de execução com um T
construtor e um Int#
componente. Você só obter um nu Int
com newtype
.
Referências :