为什么编译器无法将类型'a == a'与'True'匹配为类型系列?

时间:2016-02-03 08:15:46

标签: haskell type-families data-kinds

是否存在编译此代码的原因:

type family Foo a b :: Bool where
    Foo a b = a == b

foo :: Foo a b ~ True => Proxy a -> Proxy b
foo _ = Proxy

bar :: Proxy a -> Proxy a
bar = foo

有错误:

Couldn't match type ‘a == a’ with ‘'True’
Expected type: 'True
  Actual type: Foo a a

但如果我将类型族定义更改为

type family Foo a b :: Bool where
    Foo a a = True
    Foo a b = False

编译好吗?

(GHC-7.10.3)

1 个答案:

答案 0 :(得分:9)

由于要求Daniel Wagner提供完整的工作示例,我找到了答案。

首先完成示例:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE PolyKinds #-}
module Test where

import Data.Type.Equality(type (==))
import Data.Proxy(Proxy(..))

type family Foo a b :: Bool where
    Foo a b = a == b

foo :: Foo a b ~ True => Proxy a -> Proxy b
foo _ = Proxy

bar :: Proxy a -> Proxy a
bar = foo

这里的问题是PolyKinds pragma。没有它它运作良好。 我可能需要它以便我可以写

bar :: Proxy (a :: *) -> Proxy a

一切顺利。

原因很明显。类型系列(==)没有多边形实例(详细解释了为什么不提供此类实例here),因此我们无法减少所有等式。所以我们需要指定一种。