How does Haskell handle overloading polymorphism?

前端 未结 6 1611
余生分开走
余生分开走 2020-12-29 06:38

I have a question about Haskell polymorphism.

As I\'ve learned, there are two types of polymorphism:

  1. Parametric: where you do not spe

6条回答
  •  一生所求
    2020-12-29 06:57

    In some languages, overloading means using the same name for several functions that provide similar but different functionality, so you might try

    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
    

    which would give you the Duplicate type signature error you're getting.

    Haskell doesn't do this type of overloading, and a Haskell programmer would give these different names:

    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
    

    The reason that Haskell doesn't allow the kind of overloading I think you're asking about, is that it genuinely doesn't let you do anything that you couldn't do without it, and allowing it would make it almost impossible to do more advanced sorts of overloading. Haskell's overloading is a very powerful tool indeed; find out about type classes and constructor classes to get started.

    Actually, since String = [Char], and Haskell programmers love code reuse, they'd be far more likely to write:

    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
    

    Here Eq a is an example of a kind of overloading Haskell does allow, where splitOn will let you split any list as long as the items can be compared for equality (i.e. Haskell lets you define your own notion of equality). You can use this then to split a String, or for example a list of Strings, but you can't split a list of functions because you can't check two functions to see if they're equal. splitWith is an example of Haskell letting you treat a function just like most other data - you can pass one as an argument!

    [Note 1: words is a standard function, splitWith is in a library with a slightly different typesignature.]
    [Note 2: if you wanted to actually write these functions, here's how:

    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)
    

    ]

提交回复
热议问题