短暂的搜索并没有帮助我找到答案,所以我开始怀疑它的存在。问题很简单。我想创建一个多态函数,如下所示:
f :: String -> String
f s = show (length s)
f :: Int -> String
f i = show i
对不同数据类型定义的函数是不同的。可能吗?如果是,怎么样?
答案 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