从运算符推断类型类别
如果我使用 +
运算符,Haskell 会自动推断类型类 Num
:
> let add x y = x + y
> :t add
add :: Num a => a -> a -> a
这是否意味着我不能使用 +
运算符拥有多个类型类?
If I use the +
operator, Haskell automatically infers the type class Num
:
> let add x y = x + y
> :t add
add :: Num a => a -> a -> a
Does this mean I cannot have multiple type classes with a +
operator?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在同一个模块中不能有多个定义
+
的类型类(当然这同样适用于任何其他函数名称 - 不仅仅是+
)。如果您导入多个定义
+
的模块(无论它是否作为类型类的一部分),则在导入除其中一个之外的所有模块时,您需要隐藏+
,将除其中一个之外的所有内容导入为合格的,或者始终引用+
合格的。You can't have multiple type classes defining
+
in the same module (the same applies to any other function name of course - not just+
).And if you import multiple modules which define
+
(whether it be as part of a typeclass or not), you either need to hide+
when importing all but one of them, import all but one of them as qualified or always refer to+
qualified.请注意,
+
与其说是一个运算符,不如说它是一个函数,默认为中缀定位。这意味着它遵循与所有其他函数相同的作用域规则,以及与类型类相同的行为。具体来说,类型类定义了许多函数,这些函数在实例化该特定类型类的所有类型中都是多态的。因此,给定
Num
的定义为:我们可以得出结论,任何在其范围内包含
Num
定义的东西 - 例如任何导入Prelude
的东西,但没有Num
的限定或排除 — 在函数(+)
的范围内已经有定义;这是一个带有类型签名a ->; 的普通函数。一个-> a
,并且语法糖倾向于被假定为中缀,因此您可以编写x + y
而不是+ x y
。特别是,所有这些意味着就像您不能让 fmap 成为由类型类 Functor 和其他类型类定义的函数一样,您也不能
+
由Num
和其他类型类定义。如果你确实想在其他地方定义它,你总是可以导入相应的限定模块——但是,当你导入它们时,默认为 infix 的非字母函数名称也会变得非常笨拙。您最终会编写类似
3 M.+ 4
而不是3+4
的内容。Note that
+
is not so much an operator as it is a function which defaults to infix positioning. This means that it obeys the same kind of scoping rules as all other functions, and the same behaviour with typeclasses.Specifically, a typeclass defines a number of functions that are polymorphic across all types that instantiate that particular typeclass. So given the definition of
Num
as:we can conclude that anything that includes a definition of
Num
in its scope — such as anything importingPrelude
without qualification or exclusion ofNum
— will already have a definition in scope for the function(+)
; which is an ordinary function with type signaturea -> a -> a
, and a syntactic sugar tendency to be assumed infix, so that you'd writex + y
instead of+ x y
.In particular, all of this means that just as you can't have
fmap
be a function defined both by the typeclassFunctor
and by some other typeclass, you also can't have+
be defined both byNum
and by some other typeclass.If you do want to define it elsewhere, you can always import the corresponding module qualified — however, the non-alphabetic function names that default to infix also end up really clumsy when you import them qualified. You'd end up writing things like
3 M.+ 4
instead of3+4
.我认为问题是是否可以有多类运算符。这听起来像是对类型类如何工作的误解。如果您想实现向量空间之类的东西,其中参数具有不同的类型,您可能需要搜索类型族扩展:
对于使用此方法的库,请参阅 向量空间 包。
I think the question is whether it's possible to have multi-class operators. This sounds like a misunderstanding of how type classes work. You may want to search for the type families extension, if you want to implement something like vector spaces, where the arguments have different types:
For a library using this approach see the vector-space package.
您可以使用
+
运算符拥有多个类型类,只是Num
类实现是通过 Prelude 隐式导入的。添加语言扩展或添加一行
如果您想要一个包含两个类型类的
+
,例如Num
和A
,那么您可以创建封装两者的新类型类,You can have multiple type classes with the
+
operator, it's just that theNum
class implementation is imported implicitly via the Prelude. Either add the language extensionor add a line
If you want a
+
that includes two type classes, sayNum
andA
, then you could create a new typeclass that encapsulates both,