Haskell에서 스트림 융합의 대상인 자체 맵 함수를 작성할 수 있습니까?하스켈에서 스트림 퓨전은 어떻게 작동하나요?
왜 재귀 적 반복 목록이 융합의 대상이되지 않습니까? 그건 완전히 하스켈 패턴 일치의 좋은 표현을 죽이고 : foo (x:xx) ...
!
Prelude 루프 기능이 융합 되었습니까?
Haskell에서 스트림 융합의 대상인 자체 맵 함수를 작성할 수 있습니까?하스켈에서 스트림 퓨전은 어떻게 작동하나요?
왜 재귀 적 반복 목록이 융합의 대상이되지 않습니까? 그건 완전히 하스켈 패턴 일치의 좋은 표현을 죽이고 : foo (x:xx) ...
!
Prelude 루프 기능이 융합 되었습니까?
하스켈에서 스트림 융합은 다시 쓰기 규칙 (see the ghc documentation for more info)을 사용하여 수행됩니다. 이러한 규칙은 RULES
pragma를 사용하여 코드에서 지정할 수있는 규칙입니다.
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)
의 단일 매핑으로 다시 작성합니다.
다시 쓰기 규칙을 사용하는 데는 여러 가지 하위 규칙이 있습니다. 예를 들어 컴파일러에서 규칙이 적용되는 단계를 지정할 수 있으며 컴파일러는 해당 규칙이 올바른지 확인하는 방법이 없습니다.
다시 쓰기 결과는 여전히 형식이 검사되지만, 다시 작성 규칙에서 의미 상으로는 잘못되었을 경우 이는 순전히 사용자에게 있습니다.
고마워,하지만 그게 답의 일부일 뿐이야. 두 번째 질문을 놓쳤다. 왜 ghc가 스스로 융합을 추론 할 수없는거야? –
'Prelude.map'은 많은 'Prelude' 함수와 마찬가지로 스트림 융합이 아닌 build/foldr 융합이 적용됩니다. 이것은 스트림 융합만큼 빠르지 만 다른 범위의 경우를 포함합니다. 특히 빌드/foldr 융합은 스트림 융합과 같은 'concatMap'과 같은 병리학 적이 아닙니다. – Michael
융합이 어떻게 작동하는지 보려면이지도가 임시로 여기에서 재사용되는 것을보십시오 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
참고로이 문서는 매우 읽기 쉽습니다. http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1 .1104.7401 & rep = rep1 & type = pdf –