Haskell 是否有返回类型重载? [英] Does Haskell have return type overloading?

查看:30
本文介绍了Haskell 是否有返回类型重载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我对 Haskell 的了解,以及我对 GHC 所做的实验,Haskell 似乎具有返回类型重载(又名临时多态性).其中一个例子是 fromInteger 函数,它可以根据使用结果的位置为您提供 DoubleInteger .例如:

Based on what I've read about Haskell, and the experimentation I've done with GHC, it seems like Haskell has return type overloading (aka ad hoc polymorphism). One example of this is the fromInteger function which can give you a Double or an Integer depending on where the result is used. For example:

fd :: Double -> String
fd x = "Double"

fi :: Integer -> String
fi x = "Integer"

fd (fromInteger 5)  -- returns "Double"
fi (fromInteger 5)  -- returns "Integer"

A Gentle Introduction to Haskell 似乎同意这一点,它说:

A Gentle Introduction to Haskell seems to agree with this when it says:

目前为止我们讨论的那种多态性通常称为参数多态性.还有另一种称为临时多态性,更广为人知的是重载.以下是临时多态性的一些示例:

The kind of polymorphism that we have talked about so far is commonly called parametric polymorphism. There is another kind called ad hoc polymorphism, better known as overloading. Here are some examples of ad hoc polymorphism:

  • 文字 1、2 等通常用于表示固定精度和任意精度整数.

如果数字文字被认为是临时多态性(又名重载)的一个例子,那么对于像 fromInteger 这样的函数的结果来说似乎也是如此.

If the numeric literals are considered to be an example of ad hoc polymorphism (aka overloading), then it seems that the same is true for the result of functions like fromInteger.

事实上,我已经找到了一些关于关于堆栈溢出的其他问题的答案 这表明 Haskell 有返回类型的重载.

And in fact, I've found some answers to other questions on Stack Overflow that suggest that Haskell has overloading by return type.

然而,至少有一位 Haskell 程序员告诉我,这不是返回类型重载,而是参数多态性的一个例子,其中参数由全称量词绑定".

However, at least one Haskell programmer has told me that this isn't return type overloading, and is instead an example of "parametric polymorphism, where the parameter is bound by a universal quantifier".

认为他的意思是 fromInteger 正在从 Num(某种不确定类型)的每个实例返回一个值.

I think what he's getting at is that fromInteger is returning a value from every instance of Num (sort of a nondeterministic type).

这似乎是一个合理的解释,但据我所知,Haskell 从不让我们查看多个实例值(部分归功于 单态限制).看起来我们查看的实际实例的值也可以静态确定.因此,可以说在表达式 fd (fromInteger 5) 中,子表达式 fromInteger 5 的类型为 Double,而在表达式 fi (fromInteger 5) 中,子表达式 fromInteger 5 的类型为 Integer.

That seems like a reasonable interpretation, but as far as I can tell, Haskell never lets us look at more than one of these instance values (thanks in part to the Monomorphism restriction). It also seems like the actual instance who's value we look at can be determined statically. Because of all of this, it seems reasonable to say that in the expression fd (fromInteger 5) the subexpression fromInteger 5 is of type Double, while in the expression fi (fromInteger 5) the subexpression fromInteger 5 is of type Integer.

那么,Haskell 有返回类型重载吗?

So, does Haskell have return type overloading?

如果不是,请提供以下示例之一:

If not, please provide an example of one of the following:

  • 有效的 Haskell 代码,如果 Haskell 具有返回类型重载,则会有不同的行为
  • 如果 Haskell 具有返回类型重载,则有效的 Haskell 代码将无效
  • 如果 Haskell 具有返回类型重载,则无效的 Haskell 代码是有效的

推荐答案

好吧,一种看待它的方式是 Haskell 使用称为 类型类的字典传递翻译.(虽然这不是实现类型类的唯一方法或有关它们的原因;它只是最流行的方法.)

Well, one way to look at it is that Haskell translates the return type polymorphism that you're thinking of into parametric polymorphism, using something called the dictionary-passing translation for type classes. (Though this is not the only way to implement type classes or reason about them; it's just the most popular.)

基本上,fromInteger 在 Haskell 中有这种类型:

Basically, fromInteger has this type in Haskell:

fromInteger :: Num a => Integer -> a

这可能在内部被翻译成这样:

That might be translated internally into something like this:

fromInteger# :: NumDictionary# a -> Integer -> a
fromInteger# NumDictionary# { fromInteger = method } x = method x

data NumDictionary# a = NumDictionary# { ...
                                       , fromInteger :: Integer -> a
                                       , ... }

因此,对于每个具有 Num 实例的具体类型 T,都有一个 NumDictionary# T 值包含一个函数 fromInteger :: 整数 ->T,所有使用 Num 类型类的代码都被翻译成以字典为参数的代码.

So for each concrete type T with a Num instance, there's a NumDictionary# T value that contains a function fromInteger :: Integer -> T, and all code that uses the Num type class is translated into code that takes a dictionary as the argument.

这篇关于Haskell 是否有返回类型重载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆