我有一个函数,它有类型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