Haskell: почему условно назвать вспомогательную функцию "go"?
Я вижу go
много при чтении материала или источника Haskell, но я никогда не был очень доволен этим - (я думаю, что это имеет отрицательный оттенок "goto" в моем уме). Я начал изучать Haskell с LYAH, и именно там я взял тенденцию использовать acc
и step
при написании складок. Где же Конвенция для написания go
откуда?
самое главное, что именно это название go
должно означать?
3 ответа:
Мда! Немного археологии!
примерно с 2004 года я использовал
go
как общее имя для хвостовых рекурсивных рабочих циклов, при выполнении преобразования worker/wrapper рекурсивной функции. Я начал использовать его широко в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 #-}
из
bytestring
в августе 2005 года.это было написано в RWH, и, вероятно, был популяризирован оттуда. Кроме того,в потоке слияния библиотека, Дункан Куттс и я начал много этим заниматься.
из источников GHC
идиома идет дальше, хотя.
foldr
в GHC.База дано:foldr k z = go where go [] = z go (y:ys) = y `k` go ys
который, вероятно, где я взял трюк (я думал, что это было из тезиса Энди Гилла, но не могу найти никакого использования
go
есть). Это не дано в этой форме в Gofer, поэтому я думаю, что это впервые появилось в базе кода GHC.К 2001 Году, Саймон Марлоу использовал
go
в некоторых кодах системного уровня, поэтому мы могли бы возложить вину где-то в GHC, и эта подсказка приводит нас к источник GHC, где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' }}
это другая реализация к одному приведено в отчете H98. Копаться в реализации "числовые.lhs" однако мы обнаруживаем, что это не то же самое, что версия, которая была добавлена в GHC 2.06 в 1997 году, и очень интересный Патч от Sigbjorne Finne появляется в апреле 1998 года,добавлять
go
цикл до числового.lhs.этот говорит, что по крайней мере к 1998 году Сигбьерн добавлял
go
петли к библиотеке GHC "std", в то время как одновременно, многие модули в ядре компилятора GHC Сgo
петли. Копать дальше, это очень интересная фиксация от Will Partain в июле 1996 года добавляет цикл " go " в GHC -- код исходит от Саймона PJ, хотя!поэтому я буду называть это как идиома Глазго изобретенный людьми в Глазго, которые работали на GHC в середине 90-х, например Саймон Марлоу,Sigbjorn Финне,Будет Partain и Саймон Пейтон Джонс.
очевидно, что ответ не является правильным. Позвольте мне просто добавить небольшую деталь (поскольку, похоже, это мое письмо, на которое вы прямо ссылаетесь): go-это хорошо, потому что это всего две буквы.
О, и причина, по которой книга Yesod посвящает так много контента пакету enumerator, заключается в том, что я уже написал трехчастный учебник enumerator как серию сообщений в блоге, поэтому решил, что я могу также включить его в Книгу. Пакет перечислителя используется в нескольких местах во всем Есод, так что это актуально.
интересно, как часто
go
паттерн соответствует параметрам накопления и, в более общем плане, стратегиям продолжения кодирования, которые Митч Уонд исследовал в статье Стратегии Преобразования Программы На Основе Продолжения (одна из моих самых любимых статей). В этих случаях!--0--> функция имеет особое значение, которое затем может быть использовано для получения эффективного кода из элегантной спецификации.