Diferença entre `data` e` newtype` em Haskell

191

Qual é a diferença quando escrevo isso?

data Book = Book Int Int

versus

newtype Book = Book (Int, Int) -- "Book Int Int" is syntactically invalid
ewggwegw
fonte
Você deve pesquisar um pouco, esta pergunta já foi respondida. stackoverflow.com/questions/2649305/…
tehman
Relacionado a stackoverflow.com/questions/2649305/…
Don Stewart
Também relacionado: usos para newtype: stackoverflow.com/questions/991467/…
Don Stewart
25
Observe que newtype Book = Book Int Intnão é válido. Você pode, no entanto, ter newtype Book = Book (Int, Int)observado os dons abaixo.
Edward KMETT 5/05

Respostas:

241

Ótima pergunta!

Existem várias diferenças importantes.

Representação

  • A newtypegarante que seus dados tenham exatamente a mesma representação em tempo de execução, como o tipo que você agrupa.
  • Enquanto datadeclara 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:

  • data Book = Book Int Int

dados

  • newtype Book = Book (Int, Int)

newtype

Observe como ele tem exatamente a mesma representação que um (Int,Int), já que o Bookconstrutor é apagado.

  • data Book = Book (Int, Int)

tupla de dados

Tem um Bookconstrutor adicional não presente no arquivo newtype.

  • data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int

insira a descrição da imagem aqui

Sem ponteiros! Os dois Intcampos são campos com tamanho de palavra sem caixa no Bookconstrutor.

Tipos de dados algébricos

Devido a essa necessidade de apagar o construtor, newtypesó 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 datae newtype. Em particular, dataintroduz 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 Bookpara (,)construtor nos permite colocar um valor inferior em.

Como resultado, newtypee datapossui 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 Tconstrutor e um Int#componente. Você só obter um nu Intcom newtype.


Referências :

Don Stewart
fonte
2
Ainda acho que não sentiria falta de algo se não houvesse "novo tipo" em Haskell. As diferenças sutis adicionar complexidade à linguagem que não parecem proveitoso para mim ...
martingw
14
A diferença é muito útil por razões de desempenho. Como os construtores newtype são apagados no momento da compilação, eles não impõem a penalidade de desempenho de tempo de execução que um construtor de dados. Mas eles ainda oferecem todos os benefícios de um tipo completamente distinto e quaisquer abstrações que você deseja associar a ele. Por exemplo, existem duas maneiras diferentes pelas quais o tipo de dados da lista pode formar uma mônada. Um é incorporado ao idioma, mas se você quiser usar o outro, um novo tipo será o caminho a seguir.
Mightybyte 6/05
Ótima explicação! O que não entendo é que, se newtypeé apagado após a compilação e o tempo de execução usarem a mesma representação para tipos antigos e novos, como ainda podemos definir instâncias para os tipos antigo e novo? Como o tempo de execução pode entender qual instância usar?
damluar
3
@damluar Todos os tipos são apagados em tempo de execução, todos são totalmente resolvidos em tempo de compilação e, durante a compilação, newtypeobviamente ainda não foram apagados.
ponto
3
@damlaur Uma vez tive a mesma pergunta que você. Quando as pessoas dizem que os tipos são apagados, omitem mencionar que uma coisa NÃO É Apagada, que é uma palavra de memória usada para pesquisas no dicionário para decidir qual método de instância usar para um dado dado. As pessoas argumentam que essa palavra não é um "tipo", que eu acho que depende da sua perspectiva, mas aí está.
Gabriel L.