沒有辦法將任意約束派生爲Haskell值。
我能想到的最接近的事情是,如果你想檢查派生是否是你認爲的那樣,就是看清楚輸出。
ghc -ddump-ds -ddump-to-file A.hs
相關部分看起來是這樣的:
-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}
irred :: Show [Int]
[LclId]
irred = GHC.Show.$fShow[] @ Int GHC.Show.$fShowInt
-- RHS size: {terms: 2, types: 3, coercions: 0, joins: 0/0}
proof :: Dict (Show [Int])
[LclIdX]
proof = Cns.Dict @ (Show [Int]) irred
另一個是編寫自定義類型類儀表反映的推導,無論是在類型或價值觀,當然,這並不適用於預先存在的類型類。
{-# LANGUAGE AllowAmbiguousTypes, ConstraintKinds, GADTs, DataKinds,
FlexibleInstances, KindSignatures, MultiParamTypeClasses, RankNTypes,
ScopedTypeVariables, TypeApplications, TypeOperators,
UndecidableInstances #-}
import Data.Typeable
import Data.Kind
data (c :: [Type]) :=> (d :: Type -> Constraint)
class MyShow a d where
myshow :: a -> String
instance (d ~ ('[] :=> MyShow Int)) => MyShow Int d where
instance (MyShow a da, d ~ ('[da] :=> MyShow [a])) => MyShow [a] d where
myshowInstance :: forall a d. (Typeable d, MyShow a d) => TypeRep
myshowInstance = typeRep @_ @d Proxy
main = print (myshowInstance @[Int])
輸出可以作出更好看,例如,通過單用適當的渲染方法,而不是TypeRep
,但我希望你得到的主要思想。
:=> (': * (:=> ('[] *) (MyShow Int)) ('[] *)) (MyShow [Int])
這確實是一個有趣的練習! – nicolas