不存在量化方法时重叠实例错误的原因
Reason for overlapping instances error when not quantifying method existentially
给定以下代码,从 go
类型中删除 forall a r
失败并返回 "Overlapping instances for 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"
错误还显示 "The choice depends on the instantiation of r
" - 但不是由提供的 Proxy r
固定的吗?
这就是作用域类型变量在 Haskell 中的工作方式。请注意,您在这里重复使用 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 -- 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
错误。)
给定以下代码,从 go
类型中删除 forall a r
失败并返回 "Overlapping instances for 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"
错误还显示 "The choice depends on the instantiation of r
" - 但不是由提供的 Proxy r
固定的吗?
这就是作用域类型变量在 Haskell 中的工作方式。请注意,您在这里重复使用 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 -- 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
错误。)