根据Monad Reader第8期的文章,我已经为" Instant Insanity"编写了类型级解决方案。使用功能依赖和类型系列拼图:
fundeps解决方案大约需要200秒。而类型族版本在大约800秒内完成。
我是否可以使用任何技术使类型系列版本更有效地运行?
答案 0 :(得分:4)
我已将main
的以下定义添加到您的两个代码段中,以便解决方案显示在类型错误消息中,抱怨缺少Show
实例:
-- fundeps.hs
{-# OPTIONS_GHC -fcontext-stack=400 #-}
main = print $ solutions (undefined :: Cubes)
-- families-open.hs
{-# OPTIONS_GHC -ftype-function-depth=400 #-}
data Proxy a = Proxy
main = print (Proxy :: Proxy (Solutions Cubes))
并使用GHC 7.8.3进行编译以获得一些基线时间:
fundeps.hs
:23s families-open.hs
:46s 我发现只是将类型系列版本转换为使用封闭类型系列(代码here)可以加快它的速度,从而将差异分开:
families-closed.hs
:36s 我认为通过使用DataKinds
(代码here)给类型系列提供严格的类型可以加快速度,但令人惊讶的是,这让我回到原点:
families-closed-datakinds.hs
:44s 但是,至少它产生了所有四个版本中最易读的输出:
No instance for (Show
(Proxy
'['['Cube 'G 'B 'W 'R 'B 'G, 'Cube 'W 'G 'B 'W 'R 'R,
'Cube 'R 'W 'R 'B 'G 'R, 'Cube 'B 'R 'G 'G 'W 'W],
'['Cube 'G 'B 'R 'W 'B 'G, 'Cube 'R 'R 'W 'B 'G 'W,
'Cube 'R 'G 'B 'R 'W 'R, 'Cube 'W 'W 'G 'G 'R 'B],
'['Cube 'G 'W 'R 'B 'B 'G, 'Cube 'W 'B 'W 'R 'G 'R,
'Cube 'R 'R 'B 'G 'W 'R, 'Cube 'B 'G 'G 'W 'R 'W],
'['Cube 'G 'R 'W 'B 'B 'G, 'Cube 'R 'W 'B 'G 'R 'W,
'Cube 'R 'B 'R 'W 'G 'R, 'Cube 'W 'G 'G 'R 'W 'B],
'['Cube 'G 'R 'B 'B 'W 'G, 'Cube 'W 'W 'R 'G 'B 'R,
'Cube 'R 'B 'G 'W 'R 'R, 'Cube 'B 'G 'W 'R 'G 'W],
'['Cube 'G 'W 'B 'B 'R 'G, 'Cube 'R 'B 'G 'R 'W 'W,
'Cube 'R 'R 'W 'G 'B 'R, 'Cube 'W 'G 'R 'W 'G 'B],
'['Cube 'G 'B 'B 'W 'R 'G, 'Cube 'W 'R 'G 'B 'W 'R,
'Cube 'R 'G 'W 'R 'B 'R, 'Cube 'B 'W 'R 'G 'G 'W],
'['Cube 'G 'B 'B 'R 'W 'G, 'Cube 'R 'G 'R 'W 'B 'W,
'Cube 'R 'W 'G 'B 'R 'R, 'Cube 'W 'R 'W 'G 'G 'B]]))
因此,似乎至少可以用来加速代码的一种技术是使用封闭式系列。
正如我之前评论的那样,我也在GHC 7.9开发线上尝试过这些相同的程序,并发现了一些严重的性能回归。这导致了a GHC bug ticket现在已经解决了惊人的结果:涉及类型系列的所有三个解决方案在即将到来的GHC 7.10发布上明显更快地进行了测试!
新的时间数字(截至GHC a225c70
)如下:
families-open.hs
:7s families-closed.hs
:6.5s families-closed-datakinds.hs
:7.5s 鉴于我在没有任何严谨的情况下运行这些测试,上述三个时间应该被认为是相等的,这意味着我肯定会选择封闭式系列+数据线方法打字并产生最好的输出。