Haskell에서`data`와`newtype`의 차이점


191

이 글을 쓸 때의 차이점은 무엇입니까?

data Book = Book Int Int

newtype Book = Book (Int, Int) -- "Book Int Int" is syntactically invalid

당신은 몇 가지 검색을해야합니다,이 질문은 이미 답변되었습니다. stackoverflow.com/questions/2649305/…
tehman


관련 : 새로운 유형에 대한 사용 : stackoverflow.com/questions/991467/…
Don Stewart

25
즉 참고 newtype Book = Book Int Int유효하지 않습니다. 그러나 newtype Book = Book (Int, Int)아래 dons가 언급 한대로 가질 수 있습니다 .
Edward KMETT

답변:


241

좋은 질문입니다!

몇 가지 주요 차이점이 있습니다.

대표

  • A newtype는 데이터가 랩핑하는 유형과 런타임시 정확히 동일한 표현을 갖도록 보장합니다.
  • 동안은 data런타임에 새로운 데이터 구조를 선언합니다.

여기서 핵심 newtype은 컴파일 타임에에 대한 구문 이 지워진다는 것입니다.

예 :

  • data Book = Book Int Int

데이터

  • newtype Book = Book (Int, Int)

신형

생성자가 지워 (Int,Int)지므로, 와 정확히 동일한 표현을 갖는 방법에 유의하십시오 Book.

  • data Book = Book (Int, Int)

데이터 튜플

에 추가 Book생성자가 없습니다 newtype.

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

여기에 이미지 설명을 입력하십시오

포인터가 없습니다! 두 Int필드는 Book생성자의 상자 에없는 단어 크기의 필드입니다 .

대수 데이터 타입

이 때문에 생성자를 지울 필요가 있기 때문에 newtype데이터 유형을 단일 생성자로 래핑 할 때만 작동합니다 . "대수"신형에 대한 개념은 없습니다. 즉, 다음과 같은 새로운 유형을 작성할 수 없습니다.

data Maybe a = Nothing
             | Just a

생성자가 둘 이상이므로 쓸 수 없어

newtype Book = Book Int Int

엄밀

생성자 사이의 엄격에 아주 미묘한 차이로 리드를 삭제된다는 사실 datanewtype. 특히, data"리프팅 된"유형을 소개합니다. 이는 본질적으로 최저값으로 평가할 수있는 추가 방법이 있다는 의미입니다. 에는 런타임에 추가 생성자가 없으므로이 newtype속성은 유지되지 않습니다.

Bookto (,)생성자 에 추가 포인터를 사용하면 최저 값을 넣을 수 있습니다.

그 결과, newtypedata같이 약간 다른 엄격 속성이 하스켈 위키 문서에 설명되어 있습니다 .

언 박싱

생성자가 없으므로의 구성 요소를 개봉하는 것은 이치에 맞지 않습니다 newtype. 작성하는 것이 합리적이지만 :

data T = T {-# UNPACK #-}!Int

T생성자와 Int#구성 요소 가 포함 된 런타임 객체를 생성합니다 . 당신은 베어 얻을 Int로를 newtype.


참고 문헌 :


2
Haskell에 "newtype"이 없다면 여전히 뭔가를 놓칠 것이라고 생각하지 않습니다. 미묘한 차이는 나에게
가치

14
이 차이는 성능상의 이유로 매우 유용합니다. newtype 생성자는 컴파일 타임에 지워 지므로 데이터 생성자가하는 런타임 성능 저하를 초래하지 않습니다. 그러나 그들은 여전히 ​​당신에게 완전히 다른 유형의 모든 이점과 당신이 그와 관련된 추상화를 제공합니다. 예를 들어,리스트 데이터 유형이 모나드를 형성 할 수있는 두 가지 방법이 있습니다. 하나는 언어에 내장되어 있지만 다른 언어를 사용하려면 새로운 유형이 필요합니다.
mightybyte

좋은 설명! 이해하지 못하는 것은 newtype컴파일 및 런타임에서 이전 및 새 유형에 대해 동일한 표현을 사용하는 경우 지워지면 어떻게 이전 및 새 유형의 인스턴스를 정의 할 수 있습니까? 런타임에서 사용할 인스턴스를 어떻게 이해할 수 있습니까?
damluar

3
@damluar 모든 유형은 런타임에 지워지고 컴파일시 모두 완전히 해결되며 컴파일 중에는 newtype지워지지 않습니다.
세미콜론

3
@ damlaur 나는 한 번 당신과 같은 질문을했습니다. 사람들이 유형이 지워 졌다고 말할 때, IS N'T 지워지지 않은 한 가지는 언급하지 않습니다. 이는 주어진 데이터에 사용할 인스턴스 방법을 결정하기 위해 사전 검색에 사용되는 메모리 단어입니다. 사람들은이 단어가 "유형"이 아니라고 생각합니다. 그것은 당신의 관점에 달려 있다고 생각합니다.
Gabriel L.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.