В некоторых языках перегрузка означает использование одного и того же имени для нескольких функций, которые предоставляют аналогичные, но разные функции, поэтому вы можете попробовать
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
, которая выдаст вам ошибку 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
Причина, по которой Хаскелл не допускает такой перегрузки, о которой я думаю, вы спрашиваете, заключается в том, что она действительно не позволяет вам делать то, что вы не могли бы сделать без него, и разрешение этого сделало бы это почти невозможно делать более сложные виды перегрузок. Перегрузка 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
Здесь Eq a
является примером некоторой перегрузки, которую разрешает Haskell, где splitOn
позволит вам разбить любой список, если элементы можно сравнивать на равенство (т. Е. Haskell позволяет вам определить собственное понятие равенства ). Затем вы можете использовать это для разделения String или, например, списка Strings, но вы не можете разделить список функций, потому что вы не можете проверить две функции, чтобы увидеть, равны ли они. 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)
]