我有一個函數,它有類型Read a => String -> a
,是否有可能有另一個功能具有相同的名稱,做不同的事情a
是例如String
?是否有任何GHC擴展允許這樣做?Haskell中的函數類型專業化
喜歡的東西:
f :: Read a => String -> a
f = read
f :: String -> String
f = id
我有一個函數,它有類型Read a => String -> a
,是否有可能有另一個功能具有相同的名稱,做不同的事情a
是例如String
?是否有任何GHC擴展允許這樣做?Haskell中的函數類型專業化
喜歡的東西:
f :: Read a => String -> a
f = read
f :: String -> String
f = id
在Haskell,這種函數重載(廣告-hoc多態性)是通過使用類型類實現的,而不是通過在多個類型下綁定相同的名稱。
{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
class F a where f :: String -> a
instance F String where f = id
instance F Int where f = read
instance F Char where f = read
instance F Float where f = read
-- etc.
現在,f
可以對其中的F
實例已被宣佈任何類型的工作。
不幸的是,你不能逃脫如下:
instance Read a => F a where f = read
也許unintuitively,這並不不僅適用於有Read
一個實例類型聲明的F
一個實例。因爲GHC解決只用實例聲明(部分爲=>
的右側)的頭部的情況下,這實際上宣告各類a
是的F
情況下,反而使得它一個類型錯誤調用f
任何東西這不也是Read
的實例。
如果您啓用UndecidableInstances
擴展名,它會編譯,但這隻會導致其他問題。這是一個你不想冒險的兔子洞。
相反,您應該針對您打算運行的每個單獨類型聲明F
的實例。這不是一個簡單的類像這樣的一個非常繁重的,但如果你使用最新GHC的版本,可以使用以下使它稍微容易:現在
{-# LANGUAGE DefaultSignatures #-}
class F a where f :: String -> a
default f :: Read a => String -> a
f = read
,對於任何類型的是的Read
例如,你可以聲明其F
實例,而無需提供f
實施明確:
instance F Int
instance F Char
instance F Float
-- etc.
對於任何類型的無Read
情況下,你仍然必須寫明確的實施。
我得到它的工作,但我不得不打開了一堆可疑的語言選項:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE OverlappingInstances #-}
class SpecialRead a where
specialRead :: String -> a
instance Read a => SpecialRead a where
specialRead = read
instance SpecialRead String where
specialRead = id
main = do
print (specialRead "10" :: Int)
print (specialRead "10" :: String)
'FlexibleInstances'和'TypeSynonymInstances'是無爭議的;他們只是放鬆了Haskell標準強加的一些限制,但沒有什麼可擔心的。然而,'UndecidableInstances'和'OverlappingInstances'是危險區域,除非你知道你在做什麼,否則通常應該避免。 – bitbucket 2012-03-27 01:12:15
如果您只關心性能,那麼編譯器應該優化這些類型的東西。 – leftaroundabout 2012-03-27 00:31:28
我不關心性能,我想有一個版本,不需要周圍的字符串引號read'的',但工作正常'read'的一切。 – 2012-03-27 00:37:46
問題http://stackoverflow.com/questions/9870962/haskell-making-a-superclass-of-num/地址完全相同的問題;有些答案可能有用。 – 2012-03-27 01:23:32