方法重载有多少字典/参数? [英] How many dictionaries/parameters for method overloadings?
问题描述
我可以放约束超类;我可以对类中的特定方法进行限制;我可以对类的实例施加额外的限制.约束被实现为字典传递.这是否意味着方法的不同重载会获得不同数量的字典参数?考虑:
I can put constraints superclass; I can put constraints on particular methods in the class; I can put extra constraints on instances for the class. Constraints are implemented as dictionary-passing. Does that mean different overloadings for a method get different numbers of dictionary arguments? Consider:
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
没有方法没关系.
As I understand from this q, the Bar
s not having methods doesn't matter.
因此,Foo
的不同实例可能具有不同的特定于实例的约束,有些可能适用于整个实例头,有些仅适用于部分——例如 Bar5 a
代码>也许是一个.这是否意味着专门用于 (Maybe a)
的函数 foo
需要传递不同数量的字典,而不是 Int
?这是如何组织的?
So different instances of Foo
might have different instance-specific constraints, some maybe for the whole instance head, some for only part -- like Bar5 a
within the Maybe a
. Does that mean that function foo
specialised for (Maybe a)
needs a different number of dictionaries passed, vs say for Int
? How is that organised?
询问的原因是这个主题,SPJ 谈到 "bindSet
需要两个 Ord
参数在运行时,而普通的 bind
没有.(没错,但 bindSet
不是类的方法.)我想知道是否已经有一种机制可以让方法的实例采用不同数量的字典参数?
Reason for asking is this thread, where SPJ talks about "bindSet
takes two Ord
parameters at
run-time, whereas ordinary bind
does not". (Yes quite true, but bindSet
is not a method of a class.) I'm wondering if there's already a mechanism for a method's instances taking different numbers of dictionary parameters?
推荐答案
超类被编译为类字典中的附加字段,因此类定义:
Superclasses are compiled as additional fields in the class dictionary, so the class definition:
class (Bar1 a, Bar2 a) => Foo a where
foo :: Bar3 b => a -> b -> Bool
编译为具有三个字段的显式字典数据类型 Foo
的粗略等效:
compiles to the rough equivalent of an explicit dictionary data type Foo
with three fields:
{-# LANGUAGE RankNTypes #-}
data Foo a = C:Foo { $p1Foo :: Bar1 a
, $p2Foo :: Bar2 a
, foo :: forall b. Bar3 b -> a -> b -> Bool }
注意该类型中的foo
字段访问器,也作为foo
类方法函数,最终具有多态类型:
Note that the foo
field accessor in this type, which also serves as the foo
class method function, ultimately has polymorphic type:
foo :: Foo a -> Bar3 b -> a -> b -> Bool
意味着它接受四个参数:一个 Foo a
字典(它包含两个超类字典 Bar1 a
和 Bar2 a
的字段));一个 Bar3 b
字典作为一个单独的参数;然后是 a
和 b
参数,然后产生 Bool
.
meaning that it accepts four arguments: a Foo a
dictionary (which contains the fields for the two superclass dictionaries Bar1 a
and Bar2 a
); a Bar3 b
dictionary as a separate argument; and then a
and b
arguments before yielding a Bool
.
当定义了具有约束的多态实例时:
When a polymorphic instance with constraints is defined:
instance (Bar1 (Maybe a), Bar2 (Maybe a),
Bar4 (Maybe a), Bar5 a)
=> Foo (Maybe a) where
foo x y = True
这定义了一个字典函数";用于构建Maybe
s的字典.
this defines a "dictionary function" for constructing dictionaries of 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
Foo
字典是由 $fFooMaybe
调用创建的.
Note that foo
itself still always takes four arguments, but the field in the C:Foo
dictionary for a concrete Maybe X
type will be closed over the dictionaries $dBar1
, $dBar2
, $dBar4
, and $dBar5
supplied at the time the Foo
dictionary is created by a $fFooMaybe
call.
呜呜……
- 超类(
Bar1
和Bar2
)是字典中的额外字段 - 方法函数 (
foo
) 是函数值字段的类字典的字段访问器 - 如果
class
声明中的函数有额外的类约束(Bar3
),这些将被反映为字段函数值的附加参数立> - 多态实例(
instance Foo (Maybe a)
)被实现为字典工厂,实例声明中的任何约束(Bar1
、Bar2
)>、Bar4
、Bar5
) 在创建字典时被关闭,它可以复制超类并使用任何其他可用的范围内约束来构造必要的函数值对于方法
- super classes (
Bar1
andBar2
) are extra fields in the dictionary - method functions (
foo
) are field accessors for the class dictionary for function-valued fields - if there are additional class constraints (
Bar3
) on the function in theclass
declaration, these will be reflected as additional arguments to the function value of the field - polymorphic instances (
instance Foo (Maybe a)
) are implemented as dictionary factories, and any constraints in the instance declaration (Bar1
,Bar2
,Bar4
,Bar5
) are closed over in creating the dictionary, which can copy over the super classes and use any other available in-scope constraints in constructing the necessary function values for methods
方法 foo
总是采用相同数量的参数,尽管它采用的字典参数数量与例如 bar :: a ->Double
方法,没有额外的约束.当在不同类型上实例化时,额外的约束字典在为类型创建字典时通过闭包处理.
The method foo
always takes the same number of parameters, though it will take a different number of dictionary parameters than, say, a bar :: a -> Double
method with no additional constraints. When instantiated at different types, additional constraint dictionaries are handled through closures when creating the dictionary for the type.
这样说清楚了吗?
请注意,带有或不带有 -dsuppress-all
的 ghc -ddump-simpl
非常有助于弄清楚它是如何工作的.
Note that ghc -ddump-simpl
with or without -dsuppress-all
is very helpful for figuring out how this works under the hood.
这篇关于方法重载有多少字典/参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!