以静态形式解析超类约束

时间:2017-10-16 19:28:41

标签: haskell typeclass constraint-kinds

我想为具有静态指针的类型编写类型类,该指针可以释放超类约束。在这个人为的例子中,超约束是Typeable,因为现代GHC版本自动为所有类型提供实例。

实际上,超级约束是非平凡的,Static a的实例允许序列化这些约束的字典,因为forall a. StaticPtr a可以被序列化。

首先,以下代码编译没有问题,

{-# LANGUAGE StaticPointers #-}
{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}
{-# LANGUAGE UndecideableInstances, MultiParamTypeClasses #-}

import GHC.StaticPtr
import Data.Constraint
import Data.Constraint.Lifting
import Data.Typeable (Typeable)

class Typeable a => Static a where
    sdict :: Dict (Static a)

-- The 'Typeable f' constraint should be trivial, but typechecking 
-- fails without it. Is it possible to get rid of it, if not then why?
instance (Typeable f, Lifting Static f, Static a) => Static (f a) where
    sdict = Dict \\ lifting @Static @f @a

但是当我使用静态指针以所需的方式编写类时,

class Typeable a => Static a where
    sdict :: StaticPtr (Dict (Static a))

instance (Typeable f, Lifting Static f, Static a) => Static (f a) where
    sdict = static (Dict \\ lifting @Static @f @a)

GHC抱怨静态表单中的类型应用程序:

Only identifiers of top-level bindings can appear in the body of the static form:
  static (Dict \\ lifting @Static @f @a)
but the following identifiers were found instead: f a

然后我尝试让GHC完全独立解析实例,而不使用Lifting来指导类型检查器

instance (Typeable f, Static a) => Static (f a) where sdict = static Dict

但这也失败了,

• No instance for (Static a) arising from a use of ‘Dict’                                    
• In the body of a static form: Dict                                                                 
  In the expression: static Dict
  In an equation for ‘sdict’: sdict = static Dict                                                    

更单态的实例也会失败并出现非常类似的错误:No instance for (Static a)

instance Static a => Static [a] where sdict = static Dict

这让我更多地了解了GHC的类型类实例解析的工作原理:在实际解析实例之后才会应用类的超级约束。但GHC在第一个示例中能够满足Dict :: Static a => Dict (Static a),这显然需要Static a实例在范围内。

如果可能的话,有任何建议如何写这个吗?希望对constraints软件包有更多经验的人可以提供正确的扭曲来满足类型检查器。

0 个答案:

没有答案