方法重载有多少dictionaries/parameters?
How many dictionaries/parameters for method overloadings?
我可以把约束超级class;我可以在 class; 中对特定方法施加限制;我可以对 class 的实例施加额外的约束。约束以字典传递的形式实现。这是否意味着方法的不同重载会得到不同数量的字典参数?考虑:
class Bar1 a -- just some classes
class Bar2 a
class Bar3 a
class Bar4 a
class Bar5 a
class (Bar1 a, Bar2 a) => Foo a where
foo :: Bar3 b => a -> b -> Bool -- `b` is not in class head
instance (Bar1 (Maybe a), Bar2 (Maybe a), -- needed from superclass
-- ?but (Bar3 b) not needed (nor could it be expressed)
Bar4 (Maybe a), Bar5 a) -- additional instance-specific, Bar5 is for part of instance head
=> Foo (Maybe a) where
foo x y = True
据我从 了解到,Bar
没有方法并不重要。
因此 Foo
的不同实例可能具有不同的特定于实例的约束,一些可能针对整个实例头,一些可能仅针对一部分——例如 Maybe a
中的 Bar5 a
。这是否意味着专门用于 (Maybe a)
的函数 foo
需要传递不同数量的字典,而不是说 Int
?这是如何组织的?
询问的原因是 this thread,其中 SPJ 谈到“bindSet
需要两个 Ord
参数
运行-时间,而普通的 bind
没有”。(是的,很正确,但是 bindSet
不是 class 的方法。)我想知道是否已经有一个方法的实例采用不同数量的字典参数的机制?
Superclasses 被编译为 class 字典中的附加字段,因此 class 定义:
class (Bar1 a, Bar2 a) => Foo a where
foo :: Bar3 b => a -> b -> Bool
编译为具有三个字段的显式字典数据类型 Foo
的粗略等效项:
{-# LANGUAGE RankNTypes #-}
data Foo a = C:Foo { $p1Foo :: Bar1 a
, $p2Foo :: Bar2 a
, foo :: forall b. Bar3 b -> a -> b -> Bool }
注意该类型中的foo
字段访问器,也作为foo
class方法函数,最终具有多态类型:
foo :: Foo a -> Bar3 b -> a -> b -> Bool
意味着它接受四个参数:一个Foo a
字典(包含两个超级class字典Bar1 a
和Bar2 a
的字段); Bar3 b
字典作为单独的参数;然后是 a
和 b
参数,然后产生 Bool
.
定义带约束的多态实例时:
instance (Bar1 (Maybe a), Bar2 (Maybe a),
Bar4 (Maybe a), Bar5 a)
=> Foo (Maybe a) where
foo x y = True
这定义了一个“字典函数”,用于构建 Maybe
s 的字典。
$fFooMaybe :: Bar1 (Maybe a) -> Bar2 (Maybe a)
-> Bar 4 (Maybe a) -> Bar5 a -> Foo (Maybe a)
$fFooMaybe $dBar1 $dBar2 $dBar4 $dBar5 = C:Foo $dBar1 $dBar2 (\_ _ _ -> True)
请注意 foo
本身仍然始终采用四个参数,但是 C:Foo
字典中具体 Maybe X
类型的字段将在字典 $dBar1
上关闭、$dBar2
、$dBar4
和 $dBar5
在通过 $fFooMaybe
调用创建 Foo
词典时提供。
太棒了....
- super classes (
Bar1
and Bar2
) 是字典中的额外字段
- 方法函数 (
foo
) 是 class 函数值字段字典的字段访问器
- 如果
class
声明中的函数有额外的 class 约束 (Bar3
),这些将反映为字段的函数值的额外参数
- 多态实例(
instance Foo (Maybe a)
)作为字典工厂实现,实例声明中的任何约束(Bar1
、Bar2
、Bar4
、Bar5
) 在创建字典时关闭,它可以复制超 classes 并使用任何其他可用的范围内约束来构造方法 的必要函数值
方法 foo
总是采用相同数量的参数,尽管它采用的字典参数数量与没有额外约束的 bar :: a -> Double
方法不同。当以不同类型实例化时,在为该类型创建字典时通过闭包处理额外的约束字典。
这样说清楚了吗?
请注意 ghc -ddump-simpl
有或没有 -dsuppress-all
对于弄清楚它是如何工作的非常有帮助。
我可以把约束超级class;我可以在 class; 中对特定方法施加限制;我可以对 class 的实例施加额外的约束。约束以字典传递的形式实现。这是否意味着方法的不同重载会得到不同数量的字典参数?考虑:
class Bar1 a -- just some classes
class Bar2 a
class Bar3 a
class Bar4 a
class Bar5 a
class (Bar1 a, Bar2 a) => Foo a where
foo :: Bar3 b => a -> b -> Bool -- `b` is not in class head
instance (Bar1 (Maybe a), Bar2 (Maybe a), -- needed from superclass
-- ?but (Bar3 b) not needed (nor could it be expressed)
Bar4 (Maybe a), Bar5 a) -- additional instance-specific, Bar5 is for part of instance head
=> Foo (Maybe a) where
foo x y = True
据我从 Bar
没有方法并不重要。
因此 Foo
的不同实例可能具有不同的特定于实例的约束,一些可能针对整个实例头,一些可能仅针对一部分——例如 Maybe a
中的 Bar5 a
。这是否意味着专门用于 (Maybe a)
的函数 foo
需要传递不同数量的字典,而不是说 Int
?这是如何组织的?
询问的原因是 this thread,其中 SPJ 谈到“bindSet
需要两个 Ord
参数
运行-时间,而普通的 bind
没有”。(是的,很正确,但是 bindSet
不是 class 的方法。)我想知道是否已经有一个方法的实例采用不同数量的字典参数的机制?
Superclasses 被编译为 class 字典中的附加字段,因此 class 定义:
class (Bar1 a, Bar2 a) => Foo a where
foo :: Bar3 b => a -> b -> Bool
编译为具有三个字段的显式字典数据类型 Foo
的粗略等效项:
{-# LANGUAGE RankNTypes #-}
data Foo a = C:Foo { $p1Foo :: Bar1 a
, $p2Foo :: Bar2 a
, foo :: forall b. Bar3 b -> a -> b -> Bool }
注意该类型中的foo
字段访问器,也作为foo
class方法函数,最终具有多态类型:
foo :: Foo a -> Bar3 b -> a -> b -> Bool
意味着它接受四个参数:一个Foo a
字典(包含两个超级class字典Bar1 a
和Bar2 a
的字段); Bar3 b
字典作为单独的参数;然后是 a
和 b
参数,然后产生 Bool
.
定义带约束的多态实例时:
instance (Bar1 (Maybe a), Bar2 (Maybe a),
Bar4 (Maybe a), Bar5 a)
=> Foo (Maybe a) where
foo x y = True
这定义了一个“字典函数”,用于构建 Maybe
s 的字典。
$fFooMaybe :: Bar1 (Maybe a) -> Bar2 (Maybe a)
-> Bar 4 (Maybe a) -> Bar5 a -> Foo (Maybe a)
$fFooMaybe $dBar1 $dBar2 $dBar4 $dBar5 = C:Foo $dBar1 $dBar2 (\_ _ _ -> True)
请注意 foo
本身仍然始终采用四个参数,但是 C:Foo
字典中具体 Maybe X
类型的字段将在字典 $dBar1
上关闭、$dBar2
、$dBar4
和 $dBar5
在通过 $fFooMaybe
调用创建 Foo
词典时提供。
太棒了....
- super classes (
Bar1
andBar2
) 是字典中的额外字段 - 方法函数 (
foo
) 是 class 函数值字段字典的字段访问器 - 如果
class
声明中的函数有额外的 class 约束 (Bar3
),这些将反映为字段的函数值的额外参数 - 多态实例(
instance Foo (Maybe a)
)作为字典工厂实现,实例声明中的任何约束(Bar1
、Bar2
、Bar4
、Bar5
) 在创建字典时关闭,它可以复制超 classes 并使用任何其他可用的范围内约束来构造方法 的必要函数值
方法 foo
总是采用相同数量的参数,尽管它采用的字典参数数量与没有额外约束的 bar :: a -> Double
方法不同。当以不同类型实例化时,在为该类型创建字典时通过闭包处理额外的约束字典。
这样说清楚了吗?
请注意 ghc -ddump-simpl
有或没有 -dsuppress-all
对于弄清楚它是如何工作的非常有帮助。