具有RankNTypes的newtype

时间:2012-03-19 23:11:26

标签: haskell higher-rank-types newtype

如果我想声明newtype使得值的类型类型被约束为具有类型类的实例,那么我似乎可以这样做:

{-# LANGUAGE RankNTypes #-}

newtype ShowBox = ShowBox (forall a. Show a => a)

GHC编译就好了,但当我尝试实际使用ShowBox

ShowBox "hello"

我收到编译错误

<interactive>:1:18:
    Could not deduce (a ~ [Char])
    from the context (Show a)
      bound by a type expected by the context: Show a => a
      at <interactive>:1:10-24
      `a' is a rigid type variable bound by
          a type expected by the context: Show a => a at <interactive>:1:10
    In the first argument of `ShowBox', namely `"hello"'
    In the expression: ShowBox "hello"
    In an equation for `a': a = ShowBox "hello"

有没有办法让这项工作?

2 个答案:

答案 0 :(得分:19)

您向编译器承诺,您放在ShowBox中的值将具有forall a. Show a => a类型。该类型只有一个可能的值,它是_|_。我想你可能想要一个存在主义类型,看起来很相似,但意味着一些非常不同的东西。

{-# LANGUAGE ExistentialQuantification #-}

data ShowBox = forall a. Show a => ShowBox a

必须使用data,而不是newtype。在这种情况下,构造函数上的模式匹配是将Show实例放入范围的原因。由于newtype没有运行时表示,因此它们无法存储存在量化所暗示的多态见证。

答案 1 :(得分:7)

好吧,您的Show构造函数具有以下类型:

Show :: (forall a. Show a => a) -> ShowBox

您尝试将此函数应用于[Char]类型forall a. Show a => a,因为a是“Skolem变量”,只能与其他类型统一在非常严格的规则下(其他人将能够比我更好地解释)。

您确定以下内容不是您想要的(模datanewtype模数)吗?为什么要将forall放在构造函数中?

-- Show :: Show a => a -> ShowBox
data ShowBox = forall a. Show a => Show a
相关问题