一個簡短的搜索並沒有幫助我找到答案,所以我開始懷疑它的存在。該追問很簡單:我想創建一個多態函數,像這樣:在Haskell中創建多態函數
f :: String -> String
f s = show (length s)
f :: Int -> String
f i = show i
針對不同類型有不同的定義函數的意思。這是可能的,以及如何?
一個簡短的搜索並沒有幫助我找到答案,所以我開始懷疑它的存在。該追問很簡單:我想創建一個多態函數,像這樣:在Haskell中創建多態函數
f :: String -> String
f s = show (length s)
f :: Int -> String
f i = show i
針對不同類型有不同的定義函數的意思。這是可能的,以及如何?
有多態性的兩種風格在Haskell:
首先是最一般的 - 的功能是多態的參數化,如果它均勻地表現爲所有類型的,在它的類型參數中的至少一個。
例如,函數length
是多態的 - 它返回列表的長度,無論列表中存儲了什麼類型。
length :: [a] -> Int
多態性由小寫字母變量表示。
現在,如果您有自定義行爲,您希望對某個設置的類型,那麼您有限制多態(也稱爲「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)
以下是如何使用類型族實現類似的功能。
那麼,如果你有相同的返回類型,那麼你可以在不使用類型族的情況下實現行爲,並且只使用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
你的第一個'F'沒有正確的類型。 –
另請參閱http://stackoverflow.com/questions/5671303/what-is-haskells-style-of-polymorphism –
@DonStewart:謝謝,這是一個錯字。 – aplavin