首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell有返回类型重载吗?

Haskell有返回类型重载吗?
EN

Stack Overflow用户
提问于 2012-07-10 19:03:52
回答 5查看 3.6K关注 0票数 20

根据我所读到的关于Haskell的内容,以及我对GHC所做的实验,Haskell似乎有返回类型重载(又名即席多态)。这方面的一个例子是fromInteger函数,它可以根据结果的使用位置给出一个DoubleInteger。例如:

代码语言:javascript
复制
fd :: Double -> String
fd x = "Double"

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

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

哈斯克尔的绅士介绍似乎同意这一点,它说:

到目前为止,我们讨论过的那种多态性通常被称为参数多态性。还有另一种叫做即席多态( ad多态),也就是所谓的重载。以下是一些临时多态的例子:

  • 文字1、2等常用于表示固定的和任意的精确整数。

如果数字文本被认为是即席多态(也称为重载)的一个例子,那么像fromInteger这样的函数的结果似乎也是如此。

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

然而,至少有一个Haskell程序员告诉我,这不是返回类型重载,而是一个“参数多态,参数被一个通用量词绑定”的例子。

我认为fromInteger正在从Num的每个实例中返回一个值(某种程度上是不确定的类型)。

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

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

如果没有,请举例说明以下情况之一:

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

回答 5

Stack Overflow用户

发布于 2012-07-10 19:14:26

可以这样看,Haskell将您正在考虑的返回类型多态性转换为参数多态,使用的是字典--为类型类传递翻译。(尽管这不是实现类型类的唯一方法,也不是实现它们的原因;它只是最流行的方法。)

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

代码语言:javascript
复制
fromInteger :: Num a => Integer -> a

它可能在内部被翻译成这样的东西:

代码语言:javascript
复制
fromInteger# :: NumDictionary# a -> Integer -> a
fromInteger# NumDictionary# { fromInteger = method } x = method x

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

因此,对于每个带有T实例的具体类型,都有一个包含函数fromInteger :: Integer -> TNumDictionary# T值,所有使用Num类型类的代码都被转换为以字典为参数的代码。

票数 17
EN

Stack Overflow用户

发布于 2012-07-10 19:23:14

关于Haskell式打字机的开创性论文叫做如何使即席多态性减少即席性.所以,对你的问题的回答是有条件的“是”--取决于你要求你的返回类型重载的临时程度.

换句话说:毫无疑问,特设多态与类型分类相关,因为这是发明它们的一个有动机的例子。但是,你是否认为这个结果仍然符合“返回类型重载”的资格,取决于你喜欢的定义的微妙细节。

票数 14
EN

Stack Overflow用户

发布于 2012-07-10 21:32:10

我想谈一谈你问题的一小部分:

我们所看到的实际实例的值也可以静态地确定。

这并不是很准确。考虑以下古怪的数据类型:

代码语言:javascript
复制
data PerfectlyBalancedTree a
    = Leaf a
    | Branch (PerfectlyBalancedTree (a,a))
    deriving (Eq, Ord, Show, Read)

让我们先看一下这种类型,然后再讨论好的部分。下面是PerfectlyBalancedTree Integer类型的几个典型值

代码语言:javascript
复制
Leaf 0
Branch (Leaf (0, 0))
Branch (Branch (Leaf ((0,0),(0,0))))
Branch (Branch (Branch (Leaf (((0,0),(0,0)),((0,0),(0,0))))))

实际上,您可以将这种类型的任何值可视化为n个Branch标记的初始序列,后面是一个“我们终于完成了,谢天谢地”的Leaf标记,后面是包含的类型的2^n元组。凉爽的。

现在,我们将编写一个函数来解析一个稍微方便一些的表示。下面是几个调用示例:

代码语言:javascript
复制
*Main> :t fromString
fromString :: String -> PerfectlyBalancedTree Integer
*Main> fromString "0"
Leaf 0
*Main> fromString "b(42,69)"
Branch (Leaf (42,69))
*Main> fromString "bbb(((0,0),(0,0)),((0,0),(0,0)))"
Branch (Branch (Branch (Leaf (((0,0),(0,0)),((0,0),(0,0))))))

在此过程中,编写一个稍微多一点的多态函数是很方便的。下面是:

代码语言:javascript
复制
fromString' :: Read a => String -> PerfectlyBalancedTree a
fromString' ('b':rest) = Branch (fromString' rest)
fromString' leaf = Leaf (read leaf)

现在,我们真正的功能就是具有不同类型签名的相同功能:

代码语言:javascript
复制
fromString :: String -> PerfectlyBalancedTree Integer
fromString = fromString'

但等一下..。刚才这里发生了什么?我在你身边滑倒了点东西!为什么我们不直接写这个?

代码语言:javascript
复制
fromStringNoGood :: String -> PerfectlyBalancedTree Integer
fromStringNoGood ('b':rest) = Branch (fromStringNoGood rest)
fromStringNoGood leaf = Leaf (read leaf)

原因是在递归调用中,fromStringNoGood有一个不同的类型。它不是被调用返回一个PerfectlyBalancedTree Integer,而是被调用返回一个PerfectlyBalancedTree (Integer, Integer)。我们可以为自己写这样一个函数..。

代码语言:javascript
复制
fromStringStillNoGood :: String -> PerfectlyBalancedTree Integer
fromStringStillNoGood ('b':rest) = Branch (helper rest)
fromStringStillNoGood leaf = Leaf (read leaf)

helper :: String -> PerfectlyBalancedTree (Integer, Integer)
helper ('b':rest) = Branch ({- ... what goes here, now? -})
helper leaf = Leaf (read leaf)

..。但是,这种方式存在着一个无限的回归,进入深度和深度嵌套类型的写作。

问题是,尽管我们对单纯顶级函数感兴趣,但我们仍然不能静态地确定在它使用的多态函数中调用什么类型的read!传递给我们的数据决定了应该返回哪种类型的元组readString中更多的bs意味着一个更深层次的嵌套元组。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11420126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档