Constraint tupling的可键入实例

时间:2014-09-17 14:19:49

标签: haskell data-kinds constraint-kinds

我试图为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) (,))

有没有办法推导出这样的实例?我尝试的一切都拒绝消除★ -> ★ -> ★构造函数的歧义。

2 个答案:

答案 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 - >创建实例。约束 - >约束