什么是参数多态函数?

Lun*_*nar 5 generics polymorphism haskell

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

Raf*_*ini 7

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

假设你有一对整数:

foo :: (Int, Int) 
foo = (2,5)
Run Code Online (Sandbox Code Playgroud)

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

swapInt :: (Int, Int) -> (Int, Int)
swapInt (x,y) = (y,x)
Run Code Online (Sandbox Code Playgroud)

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

swapDouble :: (Double, Double) -> (Double, Double)
swapDouble (x,y) = (y,x)
Run Code Online (Sandbox Code Playgroud)

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

swap :: (a,b) -> (b,a)
swap (x,y) = (y,x)
Run Code Online (Sandbox Code Playgroud)

这意味着什么?你告诉编译器:有一个函数交换,它取一对(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 )
Run Code Online (Sandbox Code Playgroud)

让我们理解这个名称:polymorphic是适用于许多不同类型的任何函数或数据结构.参数化导致实现多态的方式是在函数或数据结构的类型中具有"类型参数".当你写(a,b),a并且b是类型参数.

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

存在其他种类的多态性,例如,Haskell也实现了与类型类的ad hoc多态性.


eri*_*sco 6

与其一起使用的参数类型不可知的函数.

linear_search f n [] = Nothing
linear_search f n (x:xs)
    | f n x     = Just x
    | otherwise = linear_search f n xs
Run Code Online (Sandbox Code Playgroud)

我的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"
Run Code Online (Sandbox Code Playgroud)

在谈论这个功能的类型时,它表示为(a -> b -> Bool) -> a -> [b] -> Maybe b.重要的是,字母表示类型变量,意味着它们的类型可以是任何东西 - 再次是使函数参数化多态的属性.