템플릿 Haskell과 연관된 타입 동의어 얻기


257

템플리트 Haskell이 유형 클래스에 선언 된 연관된 유형 동의어의 이름 및 / 또는 선언을 찾을 수 있습니까? 나는 reify내가 원하는 것을 할 것으로 예상 했지만 필요한 정보를 모두 제공하지는 않습니다. 함수 유형 서명을 얻는 데 효과적입니다.

% ghci
GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
...
Prelude> -- I'll be inserting line breaks and whitespace for clarity
Prelude> -- in all GHCi output.
Prelude> :set -XTemplateHaskell 
Prelude> import Language.Haskell.TH
Prelude Language.Haskell.TH> class C a where f :: a -> Int
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C)
ClassI (ClassD [] Ghci1.C [PlainTV a_1627398388] []
               [SigD Ghci1.f
                     (ForallT [PlainTV a_1627398388]
                              [ClassP Ghci1.C [VarT a_1627398388]]
                              (AppT (AppT ArrowT (VarT a_1627398388))
                                    (ConT GHC.Types.Int)))])
       []

그러나 클래스에 관련 형식 동의어를 추가하면 출력에서 ​​이름이 변경되지 않습니다.

Prelude Language.Haskell.TH> :set -XTypeFamilies 
Prelude Language.Haskell.TH> class C' a where type F a :: * ; f' :: a -> Int
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C')
ClassI (ClassD [] Ghci3.C' [PlainTV a_1627405973] []
               [SigD Ghci3.f'
                     (ForallT [PlainTV a_1627405973]
                              [ClassP Ghci3.C' [VarT a_1627405973]]
                              (AppT (AppT ArrowT (VarT a_1627405973))
                                    (ConT GHC.Types.Int)))])
       []

의 이름을 알고 있으면 해당 F정보를 찾을 수 있습니다.

Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''F)
FamilyI (FamilyD TypeFam
                 Ghci3.F
                 [PlainTV a_1627405973]
                 (Just StarT))
        []

하지만 F처음부터 이름을 찾을 수 없습니다 . 유형 클래스의 인스턴스를 추가하더라도 InstanceD정의에 대한 정보는 없습니다.

Prelude Language.Haskell.TH> instance C' [a] where type F [a] = a ; f' = length
Prelude Language.Haskell.TH> f' "Haskell"
7
Prelude Language.Haskell.TH> 42 :: F [Integer]
42
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C')
ClassI (ClassD [] Ghci3.C' [PlainTV a_1627405973] []
               [SigD Ghci3.f'
                     (ForallT [PlainTV a_1627405973]
                              [ClassP Ghci3.C' [VarT a_1627405973]]
                              (AppT (AppT ArrowT (VarT a_1627405973))
                                    (ConT GHC.Types.Int)))])
       [InstanceD []
                  (AppT (ConT Ghci3.C')
                        (AppT ListT (VarT a_1627406161)))
                  []]

경우 reify작동하지 않습니다, 해결 방법은 수동으로 연관 유형의 동의어를 나열이 아닌, 거기?

이 문제는 GHC 7.8.3에서 template-haskell 패키지 버전 2.9.0.0과 함께 나타납니다. 또한 template-haskell 패키지의 버전 2.7.0.0과 함께 GHC 7.4.2에 존재했습니다. (GHC 7.6. *는 확인하지 않았지만, GHC 7.6. *에서도 확인되었다고 생각합니다.) 모든 GHC 버전에 대한 솔루션에 관심이 있습니다 ( "GHC 버전 V 에서만 수정되었습니다 "포함).


2
봤어 reifyInstances?
Kwarrtz

2
@ Kwarrtz : 방금 시도했습니다. 그래도 작동하지 않습니다. 그것은 InstanceD내가 보았던 것과 같은 것을 일으킨다 reify: putStrLn $(stringE . show =<< reifyInstances ''C' =<< sequence [[t|[Int]|]])평가한다 [InstanceD [] (AppT (ConT Ghci1.C') (AppT ListT (VarT a_1627405978))) []]. 유형 패밀리 인스턴스가 부족하다.
Antal Spector-Zabusky 5

1
reify필요한 정보를 반환하지 않는 것이 이상 하다고 생각합니다. 아마도 show일부 정보를 숨기고 있습니까? Info물체를 직접 검사 해 보셨습니까 ?
Kwarrtz

@ Kwarrtz : 인스턴스가 파생 된 인스턴스 일 뿐이며 InfoShow인스턴스와 동일 Show합니다 Dec. 당신이 물었고, 그러나 나는 또한 직접 확인할 수 없음 : putStrLn $(reify ''C' >>= \i -> case i of ClassI (ClassD _ _ _ _ [SigD _ _]) _ -> stringE "just a SigD" ; _ -> stringE "something else")생산하지 않습니다 just a SigD- 그것은 정말 유일한 것이다 [Dec]ClassD! (필수 LambdaCase). 나는 그것이 이상하다는 것에 동의한다. 그래서 내가이 질문을 물었습니다 :-)
Antal Spector-Zabusky

1
@Abel는 : - 원래 댓글이 기발한 생각을 유치하는 것만으로는 충분하지했다, 그러나 나는 우리가 폭력 계약에 있다고 생각 했다 Yuras의 답변을 유치! 나는 좋은 대답이 무엇인지에 절대적으로 동의한다 :-)
Antal Spector-Zabusky

답변:


15

아무도 요청하지 않았기 때문에 구현되지 않았습니다.

이상한 점은 TH가 자체 컴파일러를 사용하지 않는 자체 AST를 사용한다는 것입니다. 결과적으로 TH를 통해 새로운 기능 (예 : 관련 유형 군)을 자동으로 사용할 수 없습니다. 일부는 티켓을 열고 구현해야합니다.

참조 : 내부 reifyClass함수 연관된 유형 패밀리를 무시합니다 (에서 반환되는 튜플의 다섯 번째 요소 classExtraBigSig입니다 ClassATItem.의 정의도 참조하십시오 ).

기술적으로는 관련 유형 군 지원을 쉽게 구현할 수 reify있지만, AST가 관련 유형 기본값을 지원하지 않는 것처럼 보이기 때문에 TH API에서 이전 버전과 호환되지 않는 변경이 필요할 것입니다.

추가됨 : 이제 API 변경 (btw)없이 구현 되었으며 다음 ghc릴리스 에서 제공 될 예정입니다.


1
@ AntalS-Z 관련 형식 동의어 기본값을FamilyD 지원하지 않습니다 . 아마도 그것들을 사용하고 있지 않지만 전체 솔루션을 사용하려면 API 변경이 필요할 수 있습니다.
Yuras

5
@Abel, 현상금을 끝까지 열어두면 좋은 답변이 투표를 유도하는 데 도움이되는 경향이 있으므로, 좋은 답변을 신속하게 수여하는 것보다 좋은 답변을 보상하는 더 효과적인 방법입니다.
dfeuer

1
바운티 기간이 만료되었습니다. 이것은 버그 보고서 # 10891이 해결 될 때까지 또는 그렇지 않은 경우에 가장 적합한 유일한 답변 입니다. 아마도 답변에 버그 보고서에 대한 링크를 포함시키는 것이 좋습니다.
Abel

1
참고로, # 10891은 고정되어 병합 대기 중입니다.
sinan

1
@SwiftsNamesake AFAIK ghc 개발자는 TH API를 중단하지 않고 내부 AST를 자유롭게 변경하려고합니다. 아마도 다른 이유도있을 것입니다.
Yuras
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.