假设:
newtype MyVec = MyVec { unVec :: Data.Vector }
deriving (Functor, etc)
这将创建(类似)这个:
instance Functor MyVec where
fmap f = MyVec . Data.Vector.fmap f . unVec
Vector Vectors规则是否会触发并将fmap f . fmap g $ myVec
重写为fmap (f . g) myVec
?
我应该注意哪些陷阱?在GHC 7.8中解决了为容器中的新类型“支付”的问题,是吗?
答案 0 :(得分:17)
Fusion规则对函数进行操作,而不是对类型进行操作。您在MyVec上的功能不会有融合规则,除非您编写它们以重用基础规则。
E.g。
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应该已经涵盖了这一点。