"非法多态或合格类型"在实例声明中(System-F样式树)

时间:2015-11-23 19:42:21

标签: haskell polymorphism typeclass compiler-directives system-f

我正在试验在Haskell中实现System-F风格的数据结构。

我使用A <B>表示将术语A应用于类型B只是为了使其明确(也使用大写字母)。

我们说Tree <T>是值为T的二叉树类型。我们希望找到一种可以充当Tree <T>的类型。有三个构造函数:

EmptyTree <T> : (Tree <T>)
Leaf <T> : T → (Tree <T>)
Branch <T> : (Tree <T>) → (Tree <T>) → (Tree <T>)

因此,我认为,对于吉拉德来说,我们可以使用以下

Tree T = ∀ A. A → (T → A) → (A → A → A) → A

从哪个

Empty <T>
        = ΛA.λa:A.λf:(T → A).λg:(A → A → A).
            a

Leaf <T> (x:T)
        = ΛA.λa:A.λf:(T → A).λg:(A → A → A).
            f x

Branch <T> (t1:Tree <T>) (t2:Tree <T>)
        = ΛA.λa:A.λf:(T → A).λg:(A → A → A).
            g (t1 <A> a f g) (t2 <A> a f g)

我已经发现Haskell中这些东西需要的指令,而且我不认为我错过了任何东西。所以在Haskell:

{-# LANGUAGE RankNTypes #-}
type T t = forall a.a -> (t -> a) -> (a -> a -> a) -> a

empty :: T t
empty = \a _ _ -> a
leaf :: t -> T t
leaf x = \_ f _ -> f x
fork :: T t -> T t -> T t
fork t1 t2 = \a f g -> g (t1 a f g) (t2 a f g)

到目前为止,所有这些都编译并且似乎有效。当我尝试为Show类型为T t创建实例时,会出现此问题。我添加了更多指令:

{-# LANGUAGE RankNTypes, TypeSynonymInstances, FlexibleInstances #-}

和打印树的功能

displayTree :: Show t => T t -> String
displayTree t = t displayEmpty show displayFork

使用适当的帮助者displayEmpty :: StringdisplayFork :: String -> String -> String。这也编译和工作(达到美观)。现在,如果我尝试将T t实例化为Show

的实例
instance Show t => Show (T t) where
    show = displayTree

尝试编译时出现以下错误:

    Illegal polymorphic or qualified type: T t
    In the instance declaration for 'Show (T t)'

我(我想)我理解TypeSynonymInstancesFlexibleInstances的必要性及其存在的实用原因,但我不明白为什么我的类型T t 仍然不能被声明为Show的实例。有没有办法做到这一点,T t的哪些属性意味着我的代码目前存在问题?

0 个答案:

没有答案