GHC 8.0具有用户定义类型错误的功能.我正在尝试,但我不能完全做到我想要的:
{-# 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))
Run Code Online (Sandbox Code Playgroud)
工作的前四个定义main就像我期望的那样:
Pair errorUnsupported type: BoolUnsupported type: Bool对于第五个定义,我想显示Unsupported type: Bool,但GHC显示:
No instance for (Dispatch' (EqCType (TypeError ...) DoubleD) (Bool, Double))我很困惑为什么GHC得到前三个错误是正确的,但是没有在最终定义中显示我的类型错误.我正在寻找一个简要的原因解释,如果可能的话还有一个解决方法.这只是自定义类型错误实现的限制吗?