나를 괴롭히는 haskell 플랫폼의 많은 함수를 구현하는 데 매우 일반적인 패턴이 있지만 설명을 찾을 수 없습니다. 그것은 최적화를위한 중첩 된 함수의 사용에 관한 것입니다.하스켈 플랫폼 : 중첩 된 함수와 최적화
꼬리 재귀를 만들기 위해 where 절에서 중첩 된 함수를 사용하는 이유는 매우 명확합니다 (length에서와 같이). 그러나 내부 함수가 최상위 유형과 정확히 동일한 유형 인 경우 용도는 무엇입니까? ?
-- | /O(log n)/. Is the element in the set?
member :: Ord a => a -> Set a -> Bool
member = go
where
STRICT_1_OF_2(go)
go _ Tip = False
go x (Bin _ y l r) = case compare x y of
LT -> go x l
GT -> go x r
EQ -> True
#if __GLASGOW_HASKELL__ >= 700
{-# INLINABLE member #-}
#else
{-# INLINE member #-}
#endif
내가 그것을 메모이 제이션과 함께 할 수있는 뭔가가 의심,하지만 난 모르겠어요에는 다음과 같은 하나처럼 Data.Set
module의 많은 기능에, 예에서 발생합니다.
편집 : 나는 방법이 매크로 작품을 이해
-- Use macros to define strictness of functions.
-- STRICT_x_OF_y denotes an y-ary function strict in the x-th parameter.
-- We do not use BangPatterns, because they are not in any standard and we
-- want the compilers to be compiled by as many compilers as possible.
#define STRICT_1_OF_2(fn) fn arg _ | arg `seq` False = undefined
난 아직도하지만, : dave4420가 엄격를 제안하기 때문에, 여기에 같은 모듈에서 찾을 수 있습니다 STRICT_1_OF_2
매크로에 대한 정의가 STRICT_1_OF_2(go)
과 함께 go
이 member
대신 최상위 레벨로 이동되지 않아야하는 이유를 알 수 없습니다.
어쩌면 최적화 때문이 아니라 단순한 문체 선택 때문일 수 있습니다.
편집 2 : 내가 설정 한 모듈에서 INLINABLE
및 INLINE
부분을 추가했다. 나는 그들이 언뜻보기에는 그것과 관련이 있다고 생각하지 않았습니다.
나는 그것이 엄격 성 분석과 관련이 있다고 생각한다 : 컴파일러는'member'에 대한 첫 번째 인수는 평가되어야하지만'go'에 대한 첫 번째 인수는 항상 평가되었을 것으로 추측된다. 그러나 나는 확실하지 않다. – dave4420
@ dave4420 : 의견을 보내 주셔서 감사합니다. 함수의 엄격성에 대한 정보를 더 많이 추가하여 질문을 업데이트했습니다. 이것이 도움이되기를 바랍니다. –
전적으로 문체의 문제라고 생각합니다. 그러나''이동 '에서''x' '를 자유롭게함으로써 약간의 이득을 얻을 수있을 것입니다. x가 모든 반복에서 seq : ed를 얻는다는 것을 암시하는 것처럼 보이기 때문에 이것은 벌이 쓰여진 스타일을 좋아하지 않습니다. 또한 멤버가 'x'일 필요가 없을 때 멤버를 엄격하게 만듭니다 (그러나 사소한 것입니다). – augustss