[Haskell-beginners] Re: Polymorphism question from an OO-speaking newbie

Ertugrul Soeylemez es at ertes.de
Mon May 4 12:34:28 EDT 2009


Hello Joel,

the polymorphism concept in Haskell's type system is not the same as
OOP's polymorphism.  OOP polymorphism allows you to build abstract
interfaces, whereas Haskell's polymorphism allows you to generalize both
statements and functionality.

There is no way to 'select' String and [String], as those two types have
almost nothing in common.  If you find types that have something in
common, you can express it.  "Having something in common" always means:
there is a set of functions, which is defined for both.

For example, the two types Integer and Float have in common that they
are numeric types.  Technically this means that (+), (-), (*) and a few
other functions are defined for them.  If that's all you need to know,
you can generalize the function

  foo :: Integer -> Integer -> Integer
  foo a b = a*a + b*b

to the following:

  foo :: Integral i => i -> i -> i
  foo a b = a*a + b*b

Now 'foo' is defined for every type, which is an instance of the class
Integral.  Being an instance of that class precisely means that (+), (*)
and some other functions are defined for the particular type.  Since
this is all you need to know for 'foo', there is no reason to restrict
it to Integer.

This can be applied to your example, but not verbatim.  As said, the two
types String and [String] have little in common.  If you want to write a
function with a polymorphic type, you always need to think in terms of
things you know about the types.

The types 'Maybe a' and '[a]' have a common property:  [] and Maybe are
both functors.  Informally that means that they are types, which
implement some notion of 'mapping a function over the value(s)'.
Technically it means that the 'fmap' function is defined for both:

  fmap :: Functor f => (a -> b) -> f a -> f b

Here is your original function:

  quote :: [String] -> [String]
  quote = map (\s -> "\"" ++ s ++ "\"")

Since the 'map' function is actually just a special case of 'fmap',
which is constrained to lists, knowing that you can generalize 'quote'
to any functor:

  quote :: Functor f => f String -> f String
  quote = fmap (\s -> "\"" ++ s ++ "\"")

To answer your original question:  It is impossible to write a function,
which handles both cases, because the two cases are inherently
incompatible.  In other words:  Trying to write a Haskell function,
which handles both cases, is pointless by concept.


Greets,
Ertugrul.


Joel Neely <joel.neely at gmail.com> wrote:

> Short version: Is it possible/reasonable to define a single function
> that accepts a single string or a list of strings (in which case it
> maps the single-string "flavor" over the list)?
> 
> Longer version: Thus far I know that Haskell allows me to define a
> function on a single string, then define another function that maps
> the first one across a list of strings, as in:
> 
>     *Main> let quote1 s = "\"" ++ s ++ "\""
> 
>     *Main> "Quux said " ++ quote1 "foo" ++ " loudly"
>     "Quux said \"foo\" loudly"
> 
>     *Main> let quote = map quote1
> 
>     *Main> quote ["foo", "baz", "bletch"]
>     ["\"foo\"","\"baz\"","\"bletch\""]
> 
> (BTW, is it standard terminology to say that quote lifts quote1 to lists?)
> 
> In the above I have different names for the two functions. OO
> languages such as Java allow me to overload quote to accept either
> String or List<String> (and return the same type). AFAICT, Haskell's
> parametric polymorphism allows me to define functions (e.g. length)
> which deal with "listness" concepts indifferent to the type contained
> by the list.
> 
> Am I missing something, or should I admit to OO wrongheadedness and
> accept that my inability to write a single declaration unifying:
> 
>     quote :: String -> String
>     quote :: [String] -> [String]
> 
> is an emphatic clue that I should change my expectations?
> 
> Thanks in advance for any enlightenment shed my way!
> 
> -jn-
> 



-- 
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/




More information about the Beginners mailing list