2012-11-30 2 views
7
showInt :: Int -> String 
showInt x = show x 

는 위의 코드가 Int 사전을 통과 show를 호출하거나 Show Int 인스턴스에서 선언 된 함수를 직접 호출 않습니다합니까?가능한 경우 GHC가 다형성 간접 참조를 제거합니까?

GHC는 가능한 경우 생성 된 코드에서 GHC가 다형성 간접 참조를 제거합니까?

+2

hammar로 표시되는 것처럼 자주 수행되며 때로는 수행되지 않습니다. 따라서 더 일반적인 질문은 "GHC가 사전 간접 접근을 최적화하지 못하게하는 상황은 무엇입니까?" . 확장과 관련된 몇 가지 상황을 알고 있지만, IIRC에서는 하스켈 98에서 그런 경우가 있습니다. 다형성 재귀 함수가있을 수 있습니다. –

답변

10

예.

당신이 볼 수 있듯이
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는 적절한 인스턴스 사전을 인수로 사용하지 않고 직접 참조를 삽입합니다. 기본적으로 레코드 레이블 인 접근자는 인라인 될 수 있으며 적절한 함수를 직접 참조하여 으로 남습니다.

-7

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의 경우.

+5

''Type Vector = (Float, Float) '선언은''Vector'' 타입과''(Float, Float)''타입이 완전히 동일하다는 것을 의미하며, 함수는''Vector -> Vector -> Vector '(Float, Float) -> (Float, Float) -> (Float, Float)'같은 유형을 의미하기 때문에 ' – AndrewC

+3

코드를 생성 할 때 GHC는 가능한 경우 다형 함수를 전문화하여 알려진 유형에서보다 효율적인 버전을 생성합니다. 또한 인라이닝을 사용하여 간접 참조를 해결할 수 있습니다. –

관련 문제