haskell - ¿Puede la fusión ver a través de envolturas de newtype?
optimization fusion (1)
Las reglas de fusión operan en funciones, no en tipos. Sus funciones en MyVec no tendrán reglas de fusión, a menos que las escriba para reutilizar las subyacentes.
P.ej
map :: (a -> b) -> MyVec a -> MyVec b
map f = MyVec . Vector.map f . unVec
{-# INLINE map #-}
Entonces tendríamos usos:
map f . map g
que en línea para:
MyVec . Vector.map f . unVec . MyVec . Vector.map g . unVec
Entonces, GHC debería borrar el constructor newtype, produciendo un flujo regular, adecuado para la fusión:
MyVec . Vector.map f . Vector.map g . unVec
Puede confirmar esto ejecutando GHC y observando la activación de las reglas de reescritura. Alternativamente, puede agregar su propia regla de reescritura "MyVec. UnVec", pero GHC ya debería cubrir eso.
Dado:
newtype MyVec = MyVec { unVec :: Data.Vector }
deriving (Functor, etc)
Esto creará (algo como) esto:
instance Functor MyVec where
fmap f = MyVec . Data.Vector.fmap f . unVec
Las reglas de fusión de Vectores serán fmap f . fmap g $ myVec
y reescritas fmap f . fmap g $ myVec
fmap f . fmap g $ myVec
en fmap (f . g) myVec
?
¿Hay algún error que deba tener en cuenta? Afaik, el problema en el que se "paga" por nuevos tipos en contenedores se resolvió en GHC 7.8, ¿verdad?