GHC 8.0具有user-defined type errors的功能。我正在尝试,但我不能完全做到我想做的事情:
{-# LANGUAGE DataKinds, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,
TypeFamilies, TypeOperators, UndecidableInstances #-}
import Data.Proxy
import GHC.TypeLits
data DoubleD
data IntD
type family CTypeOf x where
CTypeOf (a,b) = EqCType (CTypeOf a) (CTypeOf b)
CTypeOf Double = DoubleD
CTypeOf Int = IntD
CTypeOf a = TypeError (Text "Unsupported type: " :<>: ShowType a)
type family EqCType a b where
EqCType a a = a
EqCType a b = TypeError (Text "Pair error")
class (repr ~ CTypeOf r) => Dispatch' repr r
instance (CTypeOf r ~ DoubleD) => Dispatch' DoubleD r
instance (CTypeOf r ~ IntD) => Dispatch' IntD r
foo :: (Dispatch' (CTypeOf a) a) => Proxy a -> Int
foo _ = 3
main :: IO ()
--main = print $ foo (Proxy::Proxy (Int, Int))
--main = print $ foo (Proxy::Proxy (Int, Double))
--main = print $ foo (Proxy::Proxy Bool)
--main = print $ foo (Proxy::Proxy (Bool, Bool))
main = print $ foo (Proxy::Proxy (Bool, Double))
main
的前四个定义与我期望的一样:
Pair error
Unsupported type: Bool
Unsupported type: Bool
对于第五个定义,我希望显示Unsupported type: Bool
,但GHC显示:
No instance for (Dispatch' (EqCType (TypeError ...) DoubleD) (Bool, Double))
我很困惑为什么GHC得到前三个错误,但是没有在最终定义中显示我的类型错误。我正在寻找为什么的简要说明,以及可行的解决方法。这只是自定义类型错误实现的限制吗?