标签: parametric-polymorphism

什么是Javascript中的多态?

我已经阅读了一些我可以在互联网上找到的关于多态性的文章.但我认为我无法理解它的含义及其重要性.大多数文章没有说明为什么它很重要以及如何在OOP中实现多态行为(当然在JavaScript中).

我无法提供任何代码示例,因为我还没有想到如何实现它,所以我的问题如下:

  1. 它是什么?
  2. 为什么我们需要它?
  3. 这个怎么运作?
  4. 如何在javascript中实现这种多态行为?

我有这个例子.但是很容易理解这段代码会产生什么结果.它没有给出关于多态性本身的任何清晰的想法.

function Person(age, weight) {
    this.age = age;
    this.weight = weight;
    this.getInfo = function() {
        return "I am " + this.age + " years old " +
        "and weighs " + this.weight +" kilo.";
    }
}
function Employee(age, weight, salary) {
    this.salary = salary;
    this.age = age;
    this.weight = weight;
    this.getInfo = function() {
        return "I am " + this.age + " years old " +
        "and weighs " + this.weight +" …
Run Code Online (Sandbox Code Playgroud)

javascript oop polymorphism functional-programming parametric-polymorphism

83
推荐指数
5
解决办法
8万
查看次数

为什么Haskell的`head`在空列表中崩溃(或者为什么*不返回空列表)?(语言哲学)

其他潜在贡献者请注意:请不要犹豫,使用抽象或数学符号来表达您的观点.如果我发现你的答案不清楚,我会要求澄清,但你可以随意以舒适的方式表达自己.

要明确:我不是在寻找"安全" head,也不是head特别有意义的选择.问题的关键在于讨论head和讨论,并head'提供了背景.

我几个月来一直在用Haskell进行攻击(直到它已经成为我的主要语言),但我对一些更先进的概念以及语言哲学的细节都不了解(尽管我非常愿意学习).那么我的问题不是技术问题(除非它是,我只是没有意识到),因为它是一种哲学.

对于这个例子,我说的是head.

我想你会知道,

Prelude> head []    
*** Exception: Prelude.head: empty list
Run Code Online (Sandbox Code Playgroud)

这是从head :: [a] -> a.很公平.显然,一个人不能返回(挥手)没有类型的元素.但与此同时,定义它很简单(如果不是微不足道的话)

head' :: [a] -> Maybe a
head' []     = Nothing
head' (x:xs) = Just x
Run Code Online (Sandbox Code Playgroud)

我见过一些这方面的讨论很少在这里的某些语句的注释部分.值得注意的是,一位Alex Stangl说

"有充分的理由不让一切都"安全",并在违反前提条件时抛出异常.

我不一定质疑这个断言,但我很好奇这些"好理由"是什么.

此外,保罗约翰逊说,

'例如你可以定义"safeHead :: [a] - >也许是",但现在不是处理空列表或证明它不会发生,你必须处理"没什么"或证明它不会发生".

我从该评论中读到的语气表明,这是难度/复杂度/事物的显着增加,但我不确定我是否掌握了他在那里推出的内容.

一位Steven Pruzina说(2011年,不低于),

"有一个更深层次的原因,例如'head'不能防止崩溃.要进行多态而处理空列表,'head'必须始终返回任何特定空列表中不存在的类型变量.它将是Delphic如果Haskell能做到这一点......".

允许空列表处理会导致多态性丢失吗?如果是这样,怎么样,为什么?是否有特殊情况会使这一点变得明显?本节由@Russell O'Connor充分回答.当然,任何进一步的想法都会受到赞赏.

我会根据清晰度和建议来编辑这个.您可以提供的任何想法,论文等都将非常感激.

polymorphism haskell parametric-polymorphism

72
推荐指数
3
解决办法
2万
查看次数

参数多态与高等级类型有什么区别?

我很确定他们不一样.然而,我被"Rust不支持"高级类型(HKT)的常见概念所困扰,而是提供参数多态性.我试图了解这一点并理解它们之间的区别,但却变得越来越纠结.

根据我的理解,Rust中有高级的类型,至少是基础知识.使用"*" - 符号,HKT确实有一种例如* -> *.例如,Maybe是善良的* -> *,可以在Haskell中像这样实现.

data Maybe a = Just a | Nothing
Run Code Online (Sandbox Code Playgroud)

这里,

  • Maybe 是一个类型构造函数,需要应用于具体类型才能成为类型"*"的具体类型.
  • Just a并且Nothing是数据构造函数.

在关于Haskell的教科书中,这通常被用作高级类型的示例.但是,在Rust中它可以简单地实现为枚举,毕竟它是一个和类型:

enum Maybe<T> {
    Just(T),
    Nothing,
}
Run Code Online (Sandbox Code Playgroud)

区别在哪里?据我所知,这是一个更好的类型的完美的例子.

  1. 如果在Haskell中这被用作HKT的教科书示例,为什么说Rust没有HKT?不将Maybe枚举资格作为一个HKT?
  2. 是否应该说Rust不完全支持HKT?
  3. HKT和参数多态之间的根本区别是什么?

在查看函数时,这种混淆仍在继续,我可以编写一个参数函数,它Maybe可以将HKT作为函数参数.

fn do_something<T>(input: Maybe<T>) {
    // implementation
}
Run Code Online (Sandbox Code Playgroud)

再次,在Haskell中会是这样的

do_something :: Maybe a -> ()
do_something :: Maybe a -> ()
do_something _ = ()
Run Code Online (Sandbox Code Playgroud)

这导致了第四个问题.

  1. 对高等级类型的支持到底在哪里?什么是使Rust的类型系统无法表达HKT的最小例子? …

haskell type-theory higher-kinded-types rust parametric-polymorphism

34
推荐指数
4
解决办法
2459
查看次数

使用3级(或更高级)多态性的用例?

我已经看到了一些用于rank-2多态性的用例(最突出的例子是ST monad),但是没有比这更高级别的用例.有谁知道这样的用例?

polymorphism haskell types higher-rank-types parametric-polymorphism

26
推荐指数
2
解决办法
1010
查看次数

什么是类型量词?

许多静态类型语言具有参数多态性.例如在C#中,可以定义:

T Foo<T>(T x){ return x; }
Run Code Online (Sandbox Code Playgroud)

在呼叫站点中,您可以:

int y = Foo<int>(3);
Run Code Online (Sandbox Code Playgroud)

这些类型有时也像这样写:

Foo :: forall T. T -> T
Run Code Online (Sandbox Code Playgroud)

我听过有人说"forall就像类型级别的lambda抽象".所以Foo是一个函数,它接受一个类型(例如int),并产生一个值(例如int - > int类型的函数).许多语言推断出类型参数,因此您可以编写Foo(3)而不是Foo<int>(3).

假设我们有一个f类型的对象forall T. T -> T.我们可以用这个对象做的是首先通过Q写入传递它f<Q>.然后我们得到一个类型的值Q -> Q.但是,某些f是无效的.例如f:

f<int> = (x => x+1)
f<T> = (x => x)
Run Code Online (Sandbox Code Playgroud)

因此,如果我们"调用",f<int>那么我们会返回一个带有类型的值,int -> int一般来说,如果我们"调用",f<Q>那么我们会返回一个带有类型的值Q -> Q,这样就很好了.但是,人们普遍认为这f不是一种有效的类型forall T. T -> T,因为它根据您传递的类型做了 …

ocaml haskell types existential-type parametric-polymorphism

21
推荐指数
3
解决办法
1543
查看次数

Java中的高级多态性

我在我的大学开设了高级编程课程,我对理解这段代码的工作方式有点麻烦.

public final class GenericClass<T> {
    private void overloadedMethod(Collection<?> o) {
        System.out.println("Collection<?>");
    }

    private void overloadedMethod(List<Number> o) {
        System.out.println("List<Number>");
    }

    private void overloadedMethod(ArrayList<Integer> o) {
        System.out.println("ArrayList<Integer>");
    }

    public void method(List<T> l) {
        overloadedMethod(l);
    }

    public static void main(String[] args) {
        GenericClass<Integer> test = new GenericClass<Integer>();
        test.method(new ArrayList<Integer>());
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么这段代码会打印"Collection <?>"?

java generics polymorphism parametric-polymorphism

19
推荐指数
1
解决办法
2809
查看次数

我如何解决Go没有参数多态?

我是Go新手,但我读过Go常规不会错过参数多态.每当我尝试学习一门新语言时,我都会使用L99问题列表来进行练习.

即使我尝试写一些像第一个问题一样简单(在Go中将是单个语句,取一个切片的最后一个元素),我将如何将其写为一个接受任何类型切片的函数(使用我上面引用的那个单一语句)返回该切片的最后一个元素?

我认为即使语言没有参数多态,也必须有一些惯用的"Go"方式,以便Go常规声称他们不会错过参数多态.否则,如果示例比例如列表的最后一个元素更复杂,则需要一个函数来为每个类型执行任务.

我错过了什么?

go parametric-polymorphism

18
推荐指数
2
解决办法
2867
查看次数

为什么是forall a.一个不被认为是Int的子类型,而我可以使用类型forall a的表达式.预计会有任何一种类型的Int?

考虑以下一对函数定义,它们传递类型检查器:

a :: forall a. a
a = undefined

b :: Int
b = a
Run Code Online (Sandbox Code Playgroud)

即类型的表达式forall a. a可用于Int期望类型之一的类型.这在我看来很像子类型,但据称Haskell的类型系统缺少子类型.这些形式的可替代性有何不同?

这个问题并不具体forall a. a.其他例子包括:

id :: forall a. a -> a
id x = x

idInt :: Int -> Int
idInt = id
Run Code Online (Sandbox Code Playgroud)

haskell type-theory subtyping parametric-polymorphism

16
推荐指数
3
解决办法
679
查看次数

为什么即使禁用MonomorphismRestriction,GHC仍会在此处推断单态类型?

解决“ f = f(<*>)pure”类型提示了这一点,该类型讨论了一个更复杂的示例,但该示例也有效。

以下定义可以毫无问题地进行编译:

w :: Integral a => a
w = fromInteger w
Run Code Online (Sandbox Code Playgroud)

...当然,它在运行时无法正常工作,但这是个问题。问题的关键是,定义w本身使用的专用版本w :: Integer。显然,这一个合适的实例,因此进行类型检查。

但是,如果我们删除签名,那么GHC不会推断上述类型,而只能推断具体类型:

w' = fromInteger w'
Run Code Online (Sandbox Code Playgroud)
GHCi> :t w
w :: Integral a => a
GHCi> :t w'
w' :: Integer
Run Code Online (Sandbox Code Playgroud)

好吧,当我看到这一点时,我相当确定这是工作中的单态性限制。众所周知,例如

i = 3
Run Code Online (Sandbox Code Playgroud)
GHCi> :t i
i :: Integer
Run Code Online (Sandbox Code Playgroud)

虽然i :: Num p => p完全有可能。实际上,i :: Num p => p 可以推断出是否-XNoMonomorphismRestriction处于活动状态,即是否禁用了单态性限制。

但是,即使禁用了单态性限制, …

recursion haskell type-inference parametric-polymorphism

16
推荐指数
1
解决办法
341
查看次数

在where子句中键入签名

我写了一个类似的函数,Data.Enumerator.List.mapIterateeEnumerator一个不同Stream类型的函数兼容.

import Data.Enumerator

test :: Monad m => (ao -> ai) -> Iteratee ai m b -> Iteratee ao m b
test f iter = go $$ iter
   where go (Continue k) = continue $
            \stream -> go $$ k (fmap f stream)
         go (Yield res _) = yield res EOF
Run Code Online (Sandbox Code Playgroud)

如果我省略了类型签名go,这将工作得很好.但是,我想包括它,但我无法确定正确的签名应该是什么.这是我认为它应该是:

go :: Monad m => Step ai m b -> Iteratee ao m b

但这不起作用.
我需要一些关于找到正确类型签名的建议go.

haskell enumerator parametric-polymorphism

13
推荐指数
2
解决办法
2285
查看次数