템플리트 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 에서만 수정되었습니다 “포함).
답변
아무도 요청하지 않았기 때문에 구현되지 않았습니다.
이상한 점은 TH가 자체 컴파일러를 사용하지 않는 자체 AST를 사용한다는 것입니다. 결과적으로 TH를 통해 새로운 기능 (예 : 관련 유형 군)을 자동으로 사용할 수 없습니다. 일부는 티켓을 열고 구현해야합니다.
참조 : 내부 reifyClass
함수 는 연관된 유형 패밀리를 무시합니다 (에서 반환되는 튜플의 다섯 번째 요소 classExtraBigSig
입니다 ClassATItem
.의 정의도 참조하십시오 ).
기술적으로는 관련 유형 군 지원을 쉽게 구현할 수 reify
있지만, AST가 관련 유형 기본값을 지원하지 않는 것처럼 보이기 때문에 TH API에서 이전 버전과 호환되지 않는 변경이 필요할 것입니다.
추가됨 : 이제 API 변경 (btw)없이 구현 되었으며 다음 ghc
릴리스 에서 제공 될 예정입니다.