当不对存在的方法进行量化时,重叠实例错误的原因

时间:2015-06-29 11:40:56

标签: haskell type-families overlapping-instances

鉴于以下代码,从forall a r类型中删除go失败,并显示“Typeable(D r)重叠实例”。我想知道为什么?

{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
module M where

import Data.Typeable (Proxy, Typeable, cast)

class C r where
    data D r :: *

deriving instance Typeable D

data A = forall r . A (D r)

go :: forall r a . (Typeable a, Typeable (D r)) => a -> Proxy r -> A
go a _ = case cast a of
  Just (b :: D r) -> A b
  Nothing -> error "fail to cast"

错误还说“选择取决于r的实例化” - 但不是由提供的Proxy r固定的吗?

1 个答案:

答案 0 :(得分:4)

这是作用域类型变量在Haskell中的工作方式。请注意,您在此处重复使用go :: forall r a . (Typeable a, Typeable (D r)) => a -> Proxy r -> A go a _ = case cast a of Just (b :: D r) -> A b -- this r is the same as the r above

forall

如果没有显式go :: (Typeable a1, Typeable (D r1)) => a1 -> Proxy r1 -> A -- renaming local variables go a _ = case cast a of Just (b :: D r) -> A b -- r bears no relation to r1 ,则类型变量将被解释为签名的本地变量。也就是说,您的代码读作:

Overlapping instances

因此类型错误。

会因为{{1}}错误而感到困惑。)