如何在Haskell中创建CAF而不是CAF? [英] How to make a CAF not a CAF in Haskell?

查看:114
本文介绍了如何在Haskell中创建CAF而不是CAF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何将恒定适用表格转化为固定适用表格以阻止它在程序的整个生命周期中保留?我试过这种方法:

   -  |避免创建CAF的假参数
twoTrues ::() - > [[[Bool]]]
twoTrues _ = map(++(True:repeat False))。 trueBlock< $> [1 ..]

但它似乎不起作用 - 配置文件显示它仍然存在



我发现了一个相关的谷歌搜索结果, Simon Peyton-Jones的回复给Neil Mitchell,他问了这个问题 - 但该答案指的是一个无效的链接,不幸的是。

解决方案

泛化。 ,你能概括一下这个变量的函数吗?我的函数在命令 twoTrues 中的命名立即表明这个常量是序列 zeroTrues 中的第三个, oneTrue twoTrues threeTrues 等等 - 的确如此是。因此,将> twoTrues 概括为一个函数 nTrues ,它接受参数n 并删除 twoTrues 会从程序中删除一个CAF。

在这种情况下,我只考虑了 zeroTrues oneTrue twoTrues 我需要,但是我的程序自然可以扩展为处理 nTrues ,因为 n > 2 - 所以概括为 nTrues 意味着将一直推广到 zeroTrues oneTrue 等等。情况并非总是如此。



注意:可能还有其他CAF需要处理,无论是在代码中,或由GHC的优化产生(在这些病理学案例中并不真正优化)。

然而,这个答案可能涉及程序员的更多工作,而不是严格必要的。 。正如唐的回答所显示的那样,实际上并不需要概括。

另一方面,在某些情况下,概括一个常数可以更清楚地表明你实际上是什么做和帮助可重用性。它甚至可以揭示以更好的系统方式和/或更高效地计算一系列值的方法。



关于这种特殊情况(可以忽略) :在这种特殊情况下,我不希望将 nTrues 本身放入无限列表中(这将成为CAF,重新引入原始问题!)而不是一个功能。其中一个原因是,虽然 twoTrues 可能会以无限列表的形式有用,但我无法看到它对我的应用程序是如何有用的(无论如何),对于 nTrues 以无限列表的形式出现。


How do I make a Constant Applicative Form into, well, not a Constant Applicative Form, to stop it being retained for the lifetime of the program?

I've tried this approach:

-- | Dummy parameter to avoid creating a CAF
twoTrues :: () -> [[[Bool]]]
twoTrues _ = map (++ (True : repeat False)) . trueBlock <$> [1..]

but it doesn't seem to work - the profile shows it as still being retained and still marks it as a CAF.

I've found one relevant Google result on this, a reply by Simon Peyton-Jones to Neil Mitchell who asked precisely this question - but that answer refers to a dead link, unfortunately.

解决方案

Generalise. If you have a constant value, can you generalise this to a function of some variable? The naming of my function in the question, twoTrues, immediately suggests that this constant is the third in a sequence zeroTrues, oneTrue, twoTrues, threeTrues etc. - and indeed it is. So generalising twoTrues into a function nTrues which takes a parameter n and deleting twoTrues, would eliminate one CAF from the program.

As it happens, in this case, I had only considered the cases zeroTrues, oneTrue and twoTrues for my program because that was all I needed, but my program could naturally be extended to deal with nTrues for n > 2 - so generalising to nTrues would mean it would make sense to "generalise all the way up" to the users of zeroTrues, oneTrue etc. That would not always be the case.

Note: there might still be other CAFs to deal with, either in the code, or produced by GHC's "optimisations" (which are not really optimisations in these pathological cases).

This answer may involve more work by the programmer than is strictly necessary, however. It isn't actually necessary to generalise, as Don's answer shows.

On the other hand, in some cases, generalising a constant can make it more clear what you are actually doing, and aid reusability. It can even reveal ways to compute a series of values in a better systematic way, and/or more efficiently.

A note about this particular case (which can be ignored): In this particular case, I would not want to make nTrues itself into an infinite list (which would be a CAF again, reintroducing the original problem!) rather than a function. One reason is that while twoTrues could be useful in the form of an infinite list, I can't see how it would be useful (in my application, anyway) for nTrues to be in the form of an infinite list.

这篇关于如何在Haskell中创建CAF而不是CAF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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