템플리트 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 에서만 수정되었습니다 "포함).
InstanceD
내가 보았던 것과 같은 것을 일으킨다 reify
: putStrLn $(stringE . show =<< reifyInstances ''C' =<< sequence [[t|[Int]|]])
평가한다 [InstanceD [] (AppT (ConT Ghci1.C') (AppT ListT (VarT a_1627405978))) []]
. 유형 패밀리 인스턴스가 부족하다.
reify
필요한 정보를 반환하지 않는 것이 이상 하다고 생각합니다. 아마도 show
일부 정보를 숨기고 있습니까? Info
물체를 직접 검사 해 보셨습니까 ?
Info
의 Show
인스턴스와 동일 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
). 나는 그것이 이상하다는 것에 동의한다. 그래서 내가이 질문을 물었습니다 :-)
reifyInstances
?