类中的种类多态性

时间:2017-03-06 22:06:31

标签: haskell ghc higher-kinded-types

I recently ran into a problem使用与GADT的种类多态性。答案是提供一个完整的用户指定类型" (CUSK)我的数据类型。我已经阅读了relevant documentation,但是当我尝试将其应用于课程时,我仍然遇到了基本相同的错误。

具体来说,一旦我给了一个CUSK,下面的就会编译:

{-# LANGUAGE DataKinds, PolyKinds, GADTs #-}

data Foo (x :: k) where
  C :: Foo x -> Foo '(x,x)

但是当我将这个定义移到一个类时:

{-# LANGUAGE DataKinds, PolyKinds #-}

class Foo (f :: k -> *) where
  foo :: (f :: k1 -> *) (x :: k1) -> (f :: (k1,k1) -> *) ('(x,x) :: (k1,k1))

我收到错误:

• Expected kind ‘(k1, k1) -> *’, but ‘f’ has kind ‘k -> *’
• In the type signature:
    foo :: (f :: k1 -> *) (x :: k1) -> (f :: (k1, k1) -> *) ('(x, x) :: (k1, k1))
  In the class declaration for ‘Foo’

我希望我需要做些小事来说服GHC f在第二个例子中是多种多样的。

1 个答案:

答案 0 :(得分:9)

这是GHC 8和TypeInType的工作,它允许更多有趣的依赖形式。以下是对代码类型检查的小修改。

{-# LANGUAGE PolyKinds, RankNTypes, KindSignatures,
    DataKinds, TypeInType  #-}

module KP where

import Data.Kind

class Foo (f :: forall k. k -> *) where
  foo :: (f :: k1 -> *) (x :: k1) -> (f :: (k1,k1) -> *) ('(x,x) :: (k1,k1))

至关重要的是,在类型类参数的(ha ha!)类型中使用forall不再是语法错误。