首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >“真多态性”的例子?(最好使用Haskell)

“真多态性”的例子?(最好使用Haskell)
EN

Stack Overflow用户
提问于 2013-04-28 16:59:14
回答 2查看 1.3K关注 0票数 4

我见过很多关于“真多态性”的部分定义,例如这里这里,但是没有一个能用两个具体的例子找到这种区别的明确例子。

我知道重载+运算符是某种形式的多态性,它在Haskell和C++中的实现方式不同。有人能准确地显示两种语言中的例子有什么不同吗?

EN

回答 2

Stack Overflow用户

发布于 2013-04-28 17:08:50

您正在寻找的术语是“参数多态”,这与“即席多态”不同。

参数多态性的一个例子是在Nothing的类型签名中。

代码语言:javascript
运行
复制
Nothing :: Maybe a

类型中的a可以是任何可能的类型,因为Nothing存在于所有Maybe中,我们认为a是参数多态的,因为它可以是任何类型。

现在考虑这种类型:

代码语言:javascript
运行
复制
Just 1 :: (Num b) => Maybe b

这一次,b不能是任何类型:它只能是一个Num实例的类型。我们说b是即席多态的,因为它可以是由Num类的实例提供的一组类型的任何成员。

因此,简单地说:

  • 参数多态:可以是任何类型
  • Ad多态性:受类型类的约束
票数 6
EN

Stack Overflow用户

发布于 2013-04-28 19:45:54

您将经常遇到三种类型的多态性(使用C++和Haskell示例)。

函数语言中的参数多态性是类型系统的一个特性,其中函数的类型是在类型变量上量化的表达式。输入类型约束签名中的自由参数,这决定了输出类型。例如,map函数将函数作为其第一个参数,该参数确定输入列表和输出列表的类型。

代码语言:javascript
运行
复制
map :: (a -> b) -> [a] -> [b]

在类型理论中,签名通常是这样写的:

代码语言:javascript
运行
复制
 ∀ a. ∀ b. (a -> b) -> [a] -> [b]

C++可以通过模板实现参数多态的效果,但我认为它非常脆弱(即导致模糊的编译错误),并且缺乏已发现的函数语言中的形式主义:

代码语言:javascript
运行
复制
template <class T>
T add(T a, T b) {
    return a+b;
}

Ad多态性是指当具有不同类型签名的“查看”时,具有相同名称的函数的行为不同。在Haskell中,这是用类型类表示的。签名中的a类型被限制在实现Num类型类的类型上。

代码语言:javascript
运行
复制
(+) :: Num a => a -> a -> a

class Num a where
    (+) :: a -> a -> a

instance Num Int  where
    (+) = plusInt 

亚型多态性.在Haskell中不存在,但其他语言( Scala、ML )具有子类型多态性。在面向对象的语言中,这通常是一种语言特性,不同的对象实例以相同的名称实现方法或属性调用,并根据对象模型的语义进行分派。例如,在C++中:

代码语言:javascript
运行
复制
class Animal {
public:
 virtual void speak() = 0;
};

class Cat : public Animal {
public:
 void speak() { 
    printf("Meow");
 }
};

class Dog : public Animal {
public:
 void speak() { 
    printf("Woof");
 }
};

关于多态性,需要记住的是将核心思想与实现分开。例如,ad多态性与类型类不同,它只是它的一个表达式。

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

https://stackoverflow.com/questions/16265333

复制
相关文章

相似问题

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