2014-11-19 3 views
19

을 감안할 때 :퓨전은 newtype 래퍼를 통해 볼 수 있습니까?

instance Functor MyVec where 
    fmap f = MyVec . Data.Vector.fmap f . unVec 

윌 벡터 융합 규칙 화재 및 fmap (f . g) myVecfmap f . fmap g $ myVec를 재 작성 :

newtype MyVec = MyVec { unVec :: Data.Vector } 
    deriving (Functor, etc) 

이이 (같은)를 만들 것인가?

주의해야 할 함정이 있습니까? Afaik는 GHC 7.8에서 컨테이너의 새로운 유형을 "지불"하는 문제를 해결 했습니까?

답변

16

핵융합 규칙은 유형이 아닌 기능에 대해 작동합니다. MyVec의 함수는 기본 규칙을 재사용하기 위해 작성하지 않는 한 융합 규칙을 갖지 않습니다.

예.

map :: (a -> b) -> MyVec a -> MyVec b 
map f = MyVec . Vector.map f . unVec 
{-# INLINE map #-} 

그리고 우리가 가진 것 용도 :

map f . map g 

에 인라인됩니다

MyVec . Vector.map f . unVec . MyVec . Vector.map g . unVec 

GHC 다음 정규 스트림을 산출 newtype이란 생성자를 삭제해야 융합에 적합합니다 :

MyVec . Vector.map f . Vector.map g . unVec 

GHC를 실행하고 재 작성 규칙을 실행하여 확인하십시오. 또는 "MyVec. unVec"다시 쓰기 규칙을 추가 할 수 있지만 GHC는 이미이를 덮어 썼습니다.

+0

[The Haskell wiki] (https://www.haskell.org/haskellwiki/Performance/Data_types#Newtypes)에는 "newtype은 비용이 들지 않습니다"라고 나와 있습니다. 실제로 최적화를 방지하는 경우 실제로 수정하면 안됩니까? – gallais

+0

'map'의 정의에는 그 안에'MyVec'에 대한 호출이 있어서는 안됩니다. 'map f x = MyVec $ Vector.map f (unVec x)'? – ErikR

+1

첫 번째 질문 : 관련 재 작성 규칙을 어떻게 알 수 있습니까? '-ddump-rule-firings'을 사용할 때 나는 수 천 건의 발사를 본다. – fho

관련 문제