什么是参数多态函数?

时间:2011-05-28 17:58:04

标签: generics haskell polymorphism

任何人都可以解释这与排序算法有关吗?

3 个答案:

答案 0 :(得分:7)

让我尝试一下我能做到的最简单的事情。

假设你有一对整数:

foo :: (Int, Int) 
foo = (2,5)

并假设你想要一个交换该对上整数位置的函数。你可以这样做:

swapInt :: (Int, Int) -> (Int, Int)
swapInt (x,y) = (y,x)

但是现在如果你需要Double的类似功能,你必须再次实现它:

swapDouble :: (Double, Double) -> (Double, Double)
swapDouble (x,y) = (y,x)

您必须注意以下几点:(1)swapDoubleswapInt的代码除了类型签名外完全相同,(2)代码中没有任何地方引用任何内容取决于xy的类型。无论其类型如何,此代码均有效。因此,应该有一种方法只编写一次代码,让编译器自动为您需要的每种类型专门编写代码。这样做的方法是参数多态。对于这种特殊情况,您可以写:

swap :: (a,b) -> (b,a)
swap (x,y) = (y,x)

这意味着什么?你告诉编译器:有一个函数交换,它取一对(x,y),其中x是a类型,y是b类型,返回对(y,x)。 a和b可以是任何类型,因此该函数称为多态函数。当您将swap应用于特定对时,编译器将检查该对的类型并自动实例化适合您的元组的此函数的版本。

例如:

swap ('a', 1) = (1,'a')  -- in this case swap :: (Char, Int) -> (Int, Char) 
swap ( 0 , 5) = (5, 0 )  -- in this case swap :: (Int , Int) -> (Int, Int )

让我们理解名称:polymorphic是适用于许多不同类型的任何函数或数据结构。参数化导致实现多态的方式是在函数或数据结构的类型中具有“类型参数”。当您撰写(a,b)时,ab是类型参数。

可以实现许多数据结构,而不管其中包含的类型如何:列表,数组,映射,元组......所有这些都可以具有参数化多态实现。对它们进行操作的函数:sort,map,fold,...可以在不必引用特定类型的情况下实现,而是键入将由编译器自动专门化的参数。

存在其他类型的多态性,例如,Haskell也使用类型类实现 ad hoc 多态性。

答案 1 :(得分:6)

与其合作的参数类型无关的函数。

linear_search f n [] = Nothing
linear_search f n (x:xs)
    | f n x     = Just x
    | otherwise = linear_search f n xs

我的Haskell很生疏,所以如果有人能够纠正那些值得赞赏的评论中的错误。

这里的想法是linear_search可以在任何类型的列表上执行线性搜索;这使得函数参数化(意味着函数参数)具有多态性(因为它们可以是多种类型)。

# preforming on integers
linear_search (==) 5 [1,2,3,4,5]
# returns Just 5

# preforming on strings
linear_search (elem) 'e' ["doctor", "apron", "horse", "sky"]
# returns Just "horse"

在谈论此功能的类型时,它被称为(a -> b -> Bool) -> a -> [b] -> Maybe b。重要的是,字母表示类型变量,这意味着它们的类型可以是任何东西 - 同样也是使函数具有参数多态性的属性。

答案 2 :(得分:2)

参数多态允许一般地写入函数或数据类型,以便它可以相同地处理值而不依赖于它们的类型。参数多态是一种使语言更具表现力,同时仍保持完全静态类型安全的方法。

- 来自:http://en.wikipedia.org/wiki/Polymorphism_(computer_science)。

关于搜索,我想这更多地取决于确切的背景 - 我无法帮助那里。