融合可以看穿新型包装? [英] Can fusion see through newtype wrappers?

查看:174
本文介绍了融合可以看穿新型包装?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于:

  newtype MyVec = MyVec {unVec :: Data.Vector} 
派生(Functor等)

这会创建(类似):

 实例Functor MyVec其中
fmap f = MyVec。 Data.Vector.fmap f。 unVec

矢量融合规则会触发并重写 fmap f。 fmap g $ myVec 转换为 fmap(f。g)myVec



我应该知道的任何陷阱? Afaik在GHC 7.8中解决了支付容器中新类型的问题,解决方案

解决方案

功能,而不是类型。



例如

  map ::(a  - > b) - > MyVec a  - > MyVec b 
map f = MyVec。 Vector.map f。 unVec
{ - #INLINE map# - }

然后我们会使用:

  map f。地图g 

这将嵌入到:

  MyVec。 Vector.map f。 unVec。 MyVec。 Vector.map g。 unc 

GHC应该擦除newtype构造函数,产生一个适合融合的常规流:

  MyVec。 Vector.map f。 Vector.map g。 unVec 

您可以通过运行GHC并查看重写规则触发来确认这一点。
或者,您可以添加自己的MyVec.unVec重写规则,但是GHC应该已经覆盖了该规则。


Given:

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

This will create (something like) this:

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

Will Vectors fusion rules fire and rewrite fmap f . fmap g $ myVec into fmap (f . g) myVec?

Are there any pitfalls I should be aware of? Afaik the problem where you "pay" for new types in containers was solved in GHC 7.8, was it?

解决方案

Fusion rules operate on functions, not on types. Your functions on MyVec won't have fusion rules, unless you write them to reuse the underlying ones.

E.g.

map :: (a -> b) -> MyVec a -> MyVec b
map f = MyVec . Vector.map f . unVec
{-# INLINE map #-}

Then we'd have uses:

map f . map g

which will inline to:

MyVec . Vector.map f . unVec . MyVec . Vector.map g . unVec

GHC should then erase the newtype constructor, yielding a regular stream, suitable for fusion:

MyVec . Vector.map f . Vector.map g . unVec

You can confirm this by running GHC and looking at the rewrite rules firing. Alternatively, you can add your own "MyVec. unVec" rewrite rule, but GHC should already cover that.

这篇关于融合可以看穿新型包装?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆