哈斯克尔:为什么约定名称辅助函数“去”?

在阅读Haskell资料或来源时,我看到了很多,但是我从来没有真正感觉到这一点 – (我想它在我脑海里有“goto”的负面含义)。 我开始跟LYAH一起学习Haskell,这就是我在写褶皱的时候使用accstep的倾向。 写作大会从哪里来?

最重要的是,这个名字到底是什么意思呢?

哼! 一些考古学!

从2004年左右开始,我使用go作为尾recursion工作循环的通用名称,当执行recursion函数的工/包变换时。 我开始在bytestring广泛使用它,例如

 foldr :: (Word8 -> a -> a) -> a -> ByteString -> a foldr kv (PS xsl) = inlinePerformIO $ withForeignPtr x $ \ptr -> go v (ptr `plusPtr` (s+l-1)) (ptr `plusPtr` (s-1)) where STRICT3(go) go zpq | p == q = return z | otherwise = do c <- peek p go (c `k` z) (p `plusPtr` (-1)) q -- tail recursive {-# INLINE foldr #-} 

是2005年8月份的bytestring

这是写在RWH ,可能是从那里推广。 另外, 在stream合成库中,Duncan Coutts和我开始做了很多。

从GHC的来源

这个成语可以追溯到更远的地方。 在GHC.Base中给出如下:

 foldr kz = go where go [] = z go (y:ys) = y `k` go ys 

这可能是我捡到的伎俩(我以为这是来自Andy Gill的论文,但是找不到go那里的任何用处)。 Gofer中没有这种forms,所以我认为这首先出现在GHC代码库中。

到2001年为止,Simon Marlow正在使用一些系统级的代码,所以我们可能把责任归咎于GHC的某个地方,这个线索将我们引向GHC的源头 ,那里广泛使用工作者function:

 myCollectBinders expr = go [] expr where go bs (Lam be) = go (b:bs) e go bs e@(Note (SCC _) _) = (reverse bs, e) go bs (Cast e _) = go bs e go bs (Note _ e) = go bs e go bs e = (reverse bs, e) 

GHC 3.02和格拉斯哥

挖掘GHC的旧版本,我们看到在GHC 0.29这个成语没有出现,但GHC 3.02系列(1998),成语出现无处不在。 一个例子,在Numeric.lhs的定义中,可以追溯到1996 – 1997年:

 showInt nr | n < 0 = error "Numeric.showInt: can't show negative numbers" | otherwise = go nr where go nr = case quotRem n 10 of { (n', d) -> case chr (ord_0 + fromIntegral d) of { C# c# -> -- stricter than necessary let r' = C# c# : r in if n' == 0 then r' else go n' r' }} 

这是H98报告中的一个不同的实现。 然而,挖掘“Numeric.lhs”的实现,我们发现它与1997年添加到GHC 2.06的版本并不相同,Sigbjorne Finne的一个非常有趣的补丁出现在1998年4月, 增加了一个循环到Numeric.lhs。

这说明,至less在1998年之前,Sigbjorne正在向GHC“std”库中添加go循环,同时GHC编译器内核中的许多模块已经循环。 进一步挖掘, Will Partain在1996年7月提出的这个非常有趣的提议在GHC中增加了一个“去”循环 – 代码来自Simon PJ!

所以我打算把它称为格拉斯哥的成语,它是由格拉斯哥人在90年代中期从事GHC工作的人发明的,如Simon Marlow , Sigbjorn Finne , Will Partain和Simon Peyton Jones 。

唐的答案显然是正确的。 让我只是添加一个小细节(因为它似乎是我写的,你直接指的):去是好的,因为它只有两个字母。

呵呵,而且Yesod书中为enumerator包提供了如此多的内容的原因是因为我已经把enumerator的三部分教程写成博客文章系列了,所以我决定把它包含在书中。 枚举器包在Yesod中的许多地方都有使用,所以它是相关的。

我希望这个成语不仅适用于线性结构(因此也适用于“循环”),而且适用于分支(树状)结构。

我不知道这种转变模式多长时间对应于累积参数,更一般地说,Mitch Wand在Continuation-Based Program Transformation Strategies (我最喜欢的论文之一)中探究的连续编码策略。 在这些情况下, go函数具有特定的含义,可以用来从优雅的规范中派生出高效的代码。