Haskell 哈斯凯尔为什么要解决问题;超载;接线员?

Haskell 哈斯凯尔为什么要解决问题;超载;接线员?,haskell,operator-overloading,Haskell,Operator Overloading,针对的情况提出问题。公认的答案告诉我们,您实际上正在创建一个新函数 Ambiguous occurrence * > It could refer to either `Main.*', defined at Vec.hs:4:1 > or `Prelude.*', TypeClass的目的是允许编译器根据函数的类型选择正确的函数实现。没有他们是不可能的 为了证明这种方法的合理性,您可以阅读介绍它们的论文:[PDF]。不将其包含在Haskel

针对<代码>的情况提出问题。公认的答案告诉我们,您实际上正在创建一个新函数

但是,如果新函数要应用于标准函数以外的不同类型,为什么要这样做呢?编译器不能根据参数选择正确的吗?
是否有允许此操作的编译器标志

例如,如果没有为
[Float]*Float
定义
*

为什么编译器会哭

> Ambiguous occurrence * > It could refer to either `Main.*', defined at Vec.hs:4:1 > or `Prelude.*',
TypeClass的目的是允许编译器根据函数的类型选择正确的函数实现。没有他们是不可能的


为了证明这种方法的合理性,您可以阅读介绍它们的论文:[PDF]。

不将其包含在Haskell中是一个设计决策,而不是一个理论问题。正如您所说,许多其他语言使用类型以特殊方式消除术语之间的歧义。但是类型类具有类似的功能,另外还允许对重载的事物进行抽象。类型定向名称解析不可用


尽管如此,已经讨论了Haskell的类型定向名称解析形式(例如在解析记录字段选择器的上下文中),并且得到了一些类似于Haskell的语言的支持,例如Agda(用于数据构造函数)或Idris(更一般地说)

实际上,原因是:在Haskell中,不一定存在明确的关联“变量
x
具有类型
T

Haskell几乎与动态语言一样灵活,因为任何类型都可以是类型变量,即可以具有多态类型。但是,在动态语言(也就是OO多态性或C++模板)中,此类类型变量的类型基本上只是附加到代码中的值变量的额外信息(因此,重载操作符可以看到:参数是<代码> int <代码> >这样做,是<代码>字符串 ->这样做,在Haskell中,类型变量位于类型语言中完全独立的作用域中。这给了您许多优势,例如,没有这样的系统,更高级的多态性几乎是不可能的。然而,这也意味着更难推理重载函数应该如何解决。如果Haskell允许您只编写重载,并假设编译器在解决歧义方面做了最好的猜测,那么您常常会在意外的地方收到奇怪的错误消息。(实际上,即使没有Hindley Milner类型的系统,也很容易发生重载。C++是臭名昭著的)。
相反,Haskell选择强制重载是显式的。在重载方法之前,必须首先定义一个类型类,尽管这不能完全排除令人困惑的编译错误,但它使它们更容易避免。此外,它还允许您使用传统重载无法表达的类型解析来表达多态方法,特别是多态结果(这对于编写非常容易重用的代码非常有用)。

您可以使用
s=r*2.0 where(*)=(Main.*)
(*)作为k=map(\a->a*k)作为where(*)向编译器提示=(前奏曲*)
奇怪的是,其他地方没有问题的是哈斯克尔。谢谢你的回答。从另一方面看,这个说法似乎也是正确的。其他地方出现的许多问题,在haskell中都没有。是的,但这并不是不允许haskell中出现特殊多态性的理由。@cibercitizen1你读过我链接的文章吗?它讨论了ad-hoc多态性的一些局限性,特别是在Hindley-Milner系统中。@cibercitizen1这是一个设计决策,我认为考虑到选项,这是一个合理的决策。虽然您的问题和评论似乎表明Haskell只是选择了不实现自组织多态性本身,但自组织多态性并不是免费的:它与其他语言设计目标存在矛盾。其他语言在这里做出了不同的选择(或者,在某些情况下,他们没有选择,因为他们无论如何都无法实现他们要放弃的功能)。例如,每次我都喜欢类型推断而不是特别的多态性。没有它,我无法想象写哈斯克尔。
(*) :: [Float] -> Float -> [Float]
(*) as k = map (\a -> a*k) as  -- here: clearly Float*Float


r = [1.0, 2.0, 3.0] :: [Float]

s = r * 2.0 -- here: clearly [Float] * Float

main = do
     print r
     print s