Может ли фьюжн видеть сквозь обертки нового типа?
Дано:
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 уже должен охватывать это.