Может ли фьюжн видеть сквозь обертки нового типа?

Дано:

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

Это создаст (что-то вроде) это:

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

Будет ли Векторы слияния правил огня и переписать fmap f . fmap g $ myVec в fmap (f . g) myVec?

Есть ли какие-либо подводные камни, о которых я должен знать? Afaik проблема, где вы "платите" за новые типы в контейнерах, была решена в GHC 7.8, не так ли?

1 ответ

Правила Fusion действуют на функции, а не на типы. Ваши функции в 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 уже должен охватывать это.

Другие вопросы по тегам