내가 볼 go
하스켈 재료 나 소스를 읽을 때 많은,하지만 난 그것에 대해 정말 편안 적이 없습니다 - (나는 내 마음에 "고토"의 부정적인 내포를 가지고 추측). 나는 LYAH와 함께 Haskell을 배우기 시작했고, 그것이 내가 사용하는 경향 acc
과 step
접는 부분을 쓸 때 알게 된 곳 입니다. 글쓰기 관습은 어디 go
에서 왔습니까?
가장 중요한 것은 이름이 정확히 무엇 go
을 의미해야 하는가?
내가 볼 go
하스켈 재료 나 소스를 읽을 때 많은,하지만 난 그것에 대해 정말 편안 적이 없습니다 - (나는 내 마음에 "고토"의 부정적인 내포를 가지고 추측). 나는 LYAH와 함께 Haskell을 배우기 시작했고, 그것이 내가 사용하는 경향 acc
과 step
접는 부분을 쓸 때 알게 된 곳 입니다. 글쓰기 관습은 어디 go
에서 왔습니까?
가장 중요한 것은 이름이 정확히 무엇 go
을 의미해야 하는가?
go
내가 읽은 Haskell 자료에서는 본 적이 없습니다. 예 / 참조를 줄 수 있습니까?
답변:
흠! 일부 고고학!
2004 년경부터 go
재귀 함수의 작업자 / 래퍼 변환을 수행 할 때 꼬리 재귀 작업자 루프의 일반 이름으로 사용 했습니다. 나는 널리에서 그것을 사용하기 시작 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 년 8 월.
이것은 RWH로 작성 되었고 아마도 거기에서 대중화되었을 것입니다. 또한 스트림 퓨전 라이브러리에서 Duncan Coutts와 저는 많은 일을 시작했습니다.
GHC 소스에서
관용구는 더 멀리 돌아갑니다. foldr
GHC에서 Base 는 다음과 같이 제공됩니다.
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
아마도 내가 트릭을 집어 들었던 곳일 것입니다 (나는 이것이 Andy Gill의 논문에서 나온 것이라고 생각했지만 go
거기에서 어떤 용도도 찾을 수 없습니다 ). 그것은 하지 않습니다 나는이 처음 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 보고서에 제공된 것과는 다른 구현 입니다. 그러나 "Numeric.lhs" 구현을 살펴보면 1997 년에 GHC 2.06에 추가 된 버전과 동일하지 않으며 Sigbjorne Finne의 매우 흥미로운 패치가 1998 년 4 월에 나타납니다 . go
Numeric.lhs로 루프합니다.
이는 1998 년 적어도 Sigbjorne가 추가 것을 말한다 go
동시에, 많은 동안 GHC에 루프하는, 라이브러리를 "STD" GHC 컴파일러 코어 모듈은 한 go
루프를. 더 자세히 살펴보면 1996 년 7 월 Will Partain 의이 매우 흥미로운 커밋은 GHC에 "go"루프를 추가합니다 . 코드는 Simon PJ에서 가져온 것입니다!
그래서 저는 이것을 글래스고의 사람들이 발명 한 글래스고 관용구 라고 부를 것입니다. 그는 Simon Marlow , Sigbjorn Finne , Will Partain , Simon Peyton Jones 와 같이 90 년대 중반 GHC에서 일했습니다 .
f
, 나는 개인적으로 f'
이런 종류의 이름 으로 사용 하지만 go
, 일종의 키워드에 가까운 관용구로 사용하는 것은 내가 선택하려고 할 수있는 것입니다. showInt
동일한 가드를 여러 번 평가하는 것을 피하기 위해 관용구를 사용 한다는 점이 흥미 롭습니다.
goto
, 헬퍼 기능에 제어권을 넘겨줍니다.
loop
이미 go
규칙을 사용하는 코드를 수정하지 않는 한 사용하는 경향이 있습니다 . 나는 항상 "고리를 돌다"에서와 같이 문자 그대로 "가다"를 의미한다고 생각했습니다.
당연히 Don의 대답이 맞습니다. (당신이 직접 언급하고있는 제 글인 것 같기 때문에) 약간의 세부 사항을 추가하겠습니다. go는 두 글자 밖에 없기 때문에 좋습니다.
아, 그리고 Yesod 책이 열거 자 패키지에 너무 많은 내용을 바친 이유는 이미 블로그 포스트 시리즈로 열거 자에 대한 3 부로 구성된 자습서를 작성했기 때문에 책에 포함시키는 것이 좋습니다. 열거 자 패키지는 Yesod의 여러 곳에서 사용되므로 관련이 있습니다.
이 관용구는 선형 구조 (따라서 "루프")뿐만 아니라 분기 (나무와 같은) 구조에도 적용 할 수있을 것으로 기대합니다.
go
패턴이 얼마나 자주 축적 매개 변수에 해당 하는지 ,보다 일반적으로 Mitch Wand가 논문 Continuation-Based Program Transformation Strategies (내가 가장 좋아하는 논문 중 하나) 에서 탐색 한 연속 인코딩 전략과 일치 하는지 궁금합니다 . 이 경우 go
함수는 특별한 의미를 가지며, 우아한 사양에서 효율적인 코드를 도출하는 데 사용할 수 있습니다.
add_x
또는 consOnto_xs
.
loop
대신 내 함수 를 호출 합니다.