20

鉴于:

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

这将创建(类似)这样的:

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

Vectors 融合规则会触发并改写fmap f . fmap g $ myVecfmap (f . g) myVec?

有什么我应该注意的陷阱吗?Afaik 为容器中的新类型“付费”的问题在 GHC 7.8 中得到了解决,是吗?

4

1 回答 1

17

融合规则作用于函数,而不是类型。您在 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 应该已经涵盖了这一点。

于 2014-11-19T11:20:53.270 回答