在阅读Haskell的 Material 或源代码时,我会看到很多go
,但我从未真正感到满意-(我想它在我的脑海中具有“goto”的负面含义)。我开始与LYAH一起学习Haskell,这就是我在编写折叠时倾向于使用acc
和step
的趋势。书写go
的约定从何而来?
最重要的是,go
这个名字到底意味着什么?
最佳答案
嗯!一些考古!
从2004年左右开始,当对递归函数进行worker / wrapper转换时,我一直使用go
作为尾递归worker循环的通用名称。我开始在bytestring
中广泛使用它,例如
foldr :: (Word8 -> a -> a) -> a -> ByteString -> a
foldr k v (PS x s l) = inlinePerformIO $ withForeignPtr x $ \ptr ->
go v (ptr `plusPtr` (s+l-1)) (ptr `plusPtr` (s-1))
where
STRICT3(go)
go z p q | p == q = return z
| otherwise = do c <- peek p
go (c `k` z) (p `plusPtr` (-1)) q -- tail recursive
{-# INLINE foldr #-}
是2005年8月的
bytestring
。这写了in RWH,并且可能从那里开始流行。另外,in the stream fusion库,Duncan Coutts和我开始做很多事情。
来自GHC来源
这个习语可以追溯到更进一步。
foldr
in GHC.Base给出为:foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
这可能是我找到窍门的地方(我以为这是来自Andy Gill的论文,但是在那里找不到
go
的任何用法)。它在Gofer中没有以这种形式给出,所以我认为这首先出现在GHC代码库中。到2001年,Simon Marlow在某些系统级代码中使用了
go
,因此我们可能会将责任归咎于GHC,而这一线索使我们想到the GHC source,其中go
广泛用于辅助函数:myCollectBinders expr
= go [] expr
where
go bs (Lam b e) = 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年)中,
go
惯用语随处可见。示例Numeric.lhs
中showInt
的定义(日期为1996-1997):showInt n r
| n < 0 = error "Numeric.showInt: can't show negative numbers"
| otherwise = go n r
where
go n r =
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'
}}
这是与given in the H98 report不同的实现。深入研究"Numeric.lhs"的实现,我们发现它与1997年添加到GHC 2.06的版本不同,1998年4月,Sigbjorne Finne出现了一个非常有趣的补丁,adding a
go
loop to Numeric.lhs.这表示至少到1998年,Sigbjorne才将
go
循环添加到GHC“std”库中,而与此同时,许多modules in the GHC compiler core都具有go
循环。进一步挖掘这个 very interesting commit from Will Partain in July 1996 adds a "go" loop into GHC -代码来自Simon PJ!因此,我将其称为,这是格拉斯哥的一个成语,由90年代中期从事GHC工作的格拉斯哥人发明,例如Simon Marlow,Sigbjorn Finne,Will Partain和Simon Peyton Jones。
关于haskell - Haskell:为什么约定将辅助函数命名为 “go”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5844653/