Sud*_*ha 17 polymorphism haskell
我有一个关于Haskell多态性的问题.
据我所知,有两种类型的多态性:
参数:您没有指定输入类型.
例:
functionName :: [a] -> a
Run Code Online (Sandbox Code Playgroud)重载:作为命令式编程,即将不同的参数传递给同一个函数.
我的问题是:Haskell如何处理重载?
ham*_*mar 44
Haskell中的重载是使用类型类完成的.例如,假设您要重载一个foo
返回以下内容的函数Int
:
class Fooable a where
foo :: a -> Int
instance Fooable Int where
foo = id
instance Fooable Bool where
foo _ = 42
Run Code Online (Sandbox Code Playgroud)
但是,它们比大多数语言中的重载机制更强大.例如,您可以在返回类型上重载:
class Barable a where
bar :: Int -> a
instance Barable Int where
bar x = x + 3
instance Barable Bool where
bar x = x < 10
Run Code Online (Sandbox Code Playgroud)
有关更多示例,请查看Haskell 中的预定义类型类.
在某些语言中,重载意味着对于提供类似但不同功能的多个函数使用相同的名称,因此您可以尝试
split :: String -> [String] -- splits on whitespace
split :: Char -> String -> [String] -- splits on the given character
split :: [Char] -> String -> [String] -- splits on any of the given characters
split :: (Char -> Bool) -> String -> [String] -- splits using a function that tells you when
Run Code Online (Sandbox Code Playgroud)
这会给你带来的Duplicate type signature
错误.
Haskell不会进行这种类型的重载,而Haskell程序员会给出这些不同的名称:
words :: String -> [String] -- splits on whitespace
splitOn :: Char -> String -> [String] -- splits on the given character
splitsOn :: [Char] -> String -> [String] -- splits on any of the given characters
splitWith :: (Char -> Bool) -> String -> [String] -- splits using a function that tells you when
Run Code Online (Sandbox Code Playgroud)
Haskell不允许我认为你要问的那种超载的原因是,它真的不会让你做任何你没有做过的事情,并允许它几乎不可能做到这一点更高级的重载.Haskell的重载确实是一个非常强大的工具; 了解类型类和构造函数类以开始.
实际上,由于String
= [Char]
和Haskell程序员喜欢代码重用,他们更有可能写:
words :: String -> [String] -- splits on whitespace
splitOn :: Eq a => a -> [a] -> [[a]] -- splits on the given item
splitsOn :: Eq a => [a] -> [a] -> [[a]] -- splits on any of the given items
splitWith :: (a -> Bool) -> [a] -> [[a]] -- splits using a function that tells you when
Run Code Online (Sandbox Code Playgroud)
下面Eq a
是Haskell允许的一种重载的示例,splitOn
只要可以比较项目的相等性,就可以分割任何列表(即Haskell允许您定义自己的相等概念).您可以使用它来分割字符串,或者例如字符串列表,但是您不能拆分函数列表,因为您无法检查两个函数以查看它们是否相等.splitWith
是一个Haskell的例子,让你像处理大多数其他数据一样处理函数 - 你可以传递一个作为参数!
[注1:words
是一个标准函数,splitWith
在一个具有略微不同类型签名的库中.]
[注2:如果你想实际编写这些函数,请按以下方式:
splitWith isSplitter list = case dropWhile isSplitter list of
[] -> []
thisbit -> firstchunk : splitWith isSplitter therest
where (firstchunk, therest) = break isSplitter thisbit
-- words = splitWith isSpace -- not needed, standard function from the Prelude
splitOn c = splitWith (== c) -- notice I passed == in an argument!
splitsOn chars = splitWith (`elem` chars)
Run Code Online (Sandbox Code Playgroud)
]