我试图为tupled约束派生Typeable
实例。请参阅以下代码:
{-# LANGUAGE ConstraintKinds, GADTs #-}
{-# LANGUAGE DataKinds, PolyKinds, AutoDeriveTypeable #-}
{-# LANGUAGE StandaloneDeriving, DeriveDataTypeable #-}
import Data.Proxy
import Data.Typeable
data Foo (p :: (*, *))
data Dict ctx where
Dict :: ctx => Dict ctx
deriving (Typeable)
deriving instance Typeable '(,)
deriving instance Typeable Typeable
deriving instance Typeable Show
works :: IO ()
works = print (typeRep (Proxy :: Proxy (Foo '(Bool, Char))))
alsoWorks :: IO ()
alsoWorks = print (typeRep (Dict :: Dict (Show Bool)))
fails :: IO ()
fails = print (typeRep (Dict :: Dict (Show Bool, Typeable Bool)))
main :: IO ()
main = works >> alsoWorks >> fails
如果使用-fprint-explicit-kinds
进行编译,则会出现以下错误:
No instance for (Typeable
(Constraint -> Constraint -> Constraint) (,))
有没有办法推导出这样的实例?我尝试的一切都拒绝消除★ -> ★ -> ★
构造函数的歧义。
答案 0 :(得分:5)
GHC目前无法为Typeable
制作(,) :: Constraint -> Constraint -> Constraint
个实例或任何其他实例。类型构造函数(,)
只有类* -> * -> *
。 There is no type constructor for products of the kind Constraint -> Constraint -> Constraint
。重载构造函数(,)
以构造Constraint
s的元组和产品,但在用于生成Constraint
s的产品时没有相应的类型构造函数。
如果我们确实有Constraint
的产品的类型构造函数,我们应该能够如下定义一个实例。为此,我们假装(,)
也是类型(,) :: Constraint -> Constraint -> Constraint
的类型构造函数。要为其定义实例,我们使用KindSignatures
并导入GHC.Exts.Constraint
以便能够明确地讨论约束类型
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE KindSignatures #-}
import GHC.Exts (Constraint)
import Data.Typeable
deriving instance Typeable ((,) :: Constraint -> Constraint -> Constraint)
如果我们现在这样做,由于(,)
类型构造函数的种类,它会导致以下错误。
The signature specified kind `Constraint
-> Constraint -> Constraint',
but `(,)' has kind `* -> * -> *'
In the stand-alone deriving instance for
`Typeable ((,) :: Constraint -> Constraint -> Constraint)'
constraints包也适用于约束产品,并包含the following note。
由于当前版本的GHC中
创建实例(,)
的类型被破解,我们实际上无法为(,) :: Constraint -> Constraint -> Constraint
我认为,Edward Kmett所指的黑客是(,)
的{{1}}构造函数的重载,没有相应的类型构造函数。
答案 1 :(得分:2)
目前似乎无法实现。在constraint
的{{3}}中有一个有启发性的评论:
由于当前版本的GHC中的(,)类型的黑客,我们实际上不能为(,):: Constraint - >创建实例。约束 - >约束