在Haskell中创建多态函数

时间:2012-09-14 19:16:59

标签: function haskell polymorphism

短暂的搜索并没有帮助我找到答案,所以我开始怀疑它的存在。问题很简单。我想创建一个多态函数,如下所示:

f :: String -> String
f s = show (length s)

f :: Int -> String
f i = show i

对不同数据类型定义的函数是不同的。可能吗?如果是,怎么样?

2 个答案:

答案 0 :(得分:17)

Haskell中有两种多态:

  • 参数多态性;和
  • 有界多态性

第一个是最通用的 - 如果函数在至少一个类型参数中对所有类型均匀运行,则该函数是参数化多态的。

例如,函数length是多态的 - 它返回列表的长度,无论列表中存储的是什么类型。

length :: [a] -> Int

多态性由小写类型变量指示。

现在,如果您希望对某些类型的 set 拥有自定义行为,那么您就拥有了多边形(也称为“ad hoc”)。在Haskell中,我们使用类型类。

该类声明哪些函数可用于一组类型:

class FunnyShow a where
    funnyshow :: a -> String

然后您可以为您关注的每种类型定义实例:

instance FunnyShow Int where
    funnyshow i = show (i+1)

并且可能:

instance FunnyShow [Char] where
   funnyshow s = show (show s)

答案 1 :(得分:11)

以下是使用类型系列实现类似功能的方法。

如果您有相同的返回类型,那么您可以在不使用类型族的情况下实现该行为,并且仅使用Don建议的类型类。

但是,如果要支持更复杂的adhoc多态,最好使用类型族,例如每个实例的不同返回类型。

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE TypeFamilies #-}

class F a where
    type Out a :: * 
    f :: a -> Out a

instance F String where  
    type Out String = String
    f = show . length

instance F Int where 
    type Out Int = String 
    f = show 

instance F Float where 
    type Out Float = Float
    f = id  

在ghci

*Main> f (2::Int)
"2"

*Main> f "Hello"
"5"

*Main> f (2::Float)
2.0