2016-08-05 4 views
3

Haskell에서 스트림 융합의 대상인 자체 맵 함수를 작성할 수 있습니까?하스켈에서 스트림 퓨전은 어떻게 작동하나요?

왜 재귀 적 반복 목록이 융합의 대상이되지 않습니까? 그건 완전히 하스켈 패턴 일치의 좋은 표현을 죽이고 : foo (x:xx) ...!

Prelude 루프 기능이 융합 되었습니까?

+4

'Prelude.map'은 많은 'Prelude' 함수와 마찬가지로 스트림 융합이 아닌 build/foldr 융합이 적용됩니다. 이것은 스트림 융합만큼 빠르지 만 다른 범위의 경우를 포함합니다. 특히 빌드/foldr 융합은 스트림 융합과 같은 'concatMap'과 같은 병리학 적이 아닙니다. – Michael

+2

융합이 어떻게 작동하는지 보려면이지도가 임시로 여기에서 재사용되는 것을보십시오 github.com/ghc/ghc/blob/master/libraries/base/GHC/Base.hs#L926 이것은 일반적인 foldr/빌드 규칙은 여기에 있습니다 github.com/ghc/ghc/blob/master/libraries/base/GHC/Base.hs#L849 결과적인 내부 폴드 러가 빌드와 융합되지 않는다면, 여기에서 볼 수 있듯이 모든 것이 표준 재귀 적 맵으로 되돌아갑니다 github .com/ghc/ghc/blob/master/libraries/base/GHC/Base.hs # L927 – Michael

+0

참고로이 문서는 매우 읽기 쉽습니다. http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1 .1104.7401 & rep = rep1 & type = pdf –

답변

1

하스켈에서 스트림 융합은 다시 쓰기 규칙 (see the ghc documentation for more info)을 사용하여 수행됩니다. 이러한 규칙은 RULESpragma를 사용하여 코드에서 지정할 수있는 규칙입니다.

rewirte 규칙의 기본 아이디어는

{-# RULES 
    "map'/map'" forall f g xs. map' f (map' g xs) = map' (f . g) xs 
    #-} 
같은 것을 할 수있는, 당신은 당신이 map'map의 자신의 버전을 정의 된 경우 코드는 예를 들어, 컴파일시에 다시 쓸 수있는 방법의 집합을 지정하는 것이있다

여기에는 map'/map'이라는 다시 쓰기 규칙이 도입되었습니다. 이 규칙은 기능 번호 f의 모든 매핑을 다시 g의 일부 xs에 매핑하여이 x에 대해 (f . g)의 단일 매핑으로 다시 작성합니다.

다시 쓰기 규칙을 사용하는 데는 여러 가지 하위 규칙이 있습니다. 예를 들어 컴파일러에서 규칙이 적용되는 단계를 지정할 수 있으며 컴파일러는 해당 규칙이 올바른지 확인하는 방법이 없습니다.

다시 쓰기 결과는 여전히 형식이 검사되지만, 다시 작성 규칙에서 의미 상으로는 잘못되었을 경우 이는 순전히 사용자에게 있습니다.

+0

고마워,하지만 그게 답의 일부일 뿐이야. 두 번째 질문을 놓쳤다. 왜 ghc가 스스로 융합을 추론 할 수없는거야? –

관련 문제