showInt :: Int -> String
showInt x = show x
는 위의 코드가 Int
사전을 통과 show
를 호출하거나 Show Int
인스턴스에서 선언 된 함수를 직접 호출 않습니다합니까?가능한 경우 GHC가 다형성 간접 참조를 제거합니까?
GHC는 가능한 경우 생성 된 코드에서 GHC가 다형성 간접 참조를 제거합니까?
showInt :: Int -> String
showInt x = show x
는 위의 코드가 Int
사전을 통과 show
를 호출하거나 Show Int
인스턴스에서 선언 된 함수를 직접 호출 않습니다합니까?가능한 경우 GHC가 다형성 간접 참조를 제거합니까?
GHC는 가능한 경우 생성 된 코드에서 GHC가 다형성 간접 참조를 제거합니까?
예.
당신이 볼 수 있듯이Foo.showInt :: GHC.Types.Int -> GHC.Base.String
[... attributes omitted ...]
Foo.showInt = GHC.Show.$fShowInt_$cshow
, 그것은 GHC.Show.$fShowInt_$cshow
단지 직접 참조입니다 :이 GHC 7.4.2을 사용하여 생성 된 핵심입니다. 유추 유형 Show a => a -> String
대신 사용되도록
우리는 유형 서명을 제거하면 어떻게되는지와 비교 :
여기Foo.showInt
:: forall a_aop. GHC.Show.Show a_aop => a_aop -> GHC.Base.String
[... attributes omitted ...]
Foo.showInt =
\ (@ a_aot) ($dShow_aou :: GHC.Show.Show a_aot) (x_a9Z :: a_aot) ->
GHC.Show.show @ a_aot $dShow_aou x_a9Z
, 그것은 사전 인수 $dShow_aou
을 취하며 를 조회하기 위해 접근 기능 GHC.Show.show
를 사용 결과 함수를 인수 x_a9Z
에 적용하기 전에이 사전에서 적절한 함수.
첫 번째 경우에는 최소한 개념적으로, 구체적인 유형이 알려지기 때문에 GHC는 적절한 인스턴스 사전을 인수로 사용하지 않고 직접 참조를 삽입합니다. 기본적으로 레코드 레이블 인 접근자는 인라인 될 수 있으며 적절한 함수를 직접 참조하여 으로 남습니다.
GHC는 그렇게하지 않습니다. 일기 좋게하기위한 새로운 창조 형 생각해 GHC이 같은 함수에서 Polymorphicism을 제거 할 경우
type Vector = (Float, Float)
가 :
(!+!) :: Vector -> Vector -> Vector
(x1, y1) !+! (x2, y2) = (x1 + x2, y1 + y2)
유형이 될 것입니다 :
(!+!) :: (Float, Float) -> (Float, Float) -> (Float, Float)
을 함수, 표준이지만 Vector의 경우.
''Type Vector = (Float, Float) '선언은''Vector'' 타입과''(Float, Float)''타입이 완전히 동일하다는 것을 의미하며, 함수는''Vector -> Vector -> Vector '(Float, Float) -> (Float, Float) -> (Float, Float)'같은 유형을 의미하기 때문에 ' – AndrewC
코드를 생성 할 때 GHC는 가능한 경우 다형 함수를 전문화하여 알려진 유형에서보다 효율적인 버전을 생성합니다. 또한 인라이닝을 사용하여 간접 참조를 해결할 수 있습니다. –
hammar로 표시되는 것처럼 자주 수행되며 때로는 수행되지 않습니다. 따라서 더 일반적인 질문은 "GHC가 사전 간접 접근을 최적화하지 못하게하는 상황은 무엇입니까?" . 확장과 관련된 몇 가지 상황을 알고 있지만, IIRC에서는 하스켈 98에서 그런 경우가 있습니다. 다형성 재귀 함수가있을 수 있습니다. –