在阅读Haskell的 Material 或源代码时,我会看到很多go,但我从未真正感到满意-(我想它在我的脑海中具有“goto”的负面含义)。我开始与LYAH一起学习Haskell,这就是我在编写折叠时倾向于使用accstep的趋势。书写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.lhsshowInt的定义(日期为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 MarlowSigbjorn FinneWill PartainSimon Peyton Jones

关于haskell - Haskell:为什么约定将辅助函数命名为 “go”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5844653/

10-12 00:36
查看更多