Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can two different typeclasses have the same method names?

Suppose I have

class Foo a where
    (++=) :: a -> a -> a
    cool  :: (a -> b -> b) -> a -> b

and want to make

class Bar a where
    (++=) :: (a -> b) -> a -> b
    magic :: a -> b

which has an overlapping method name, (++=). Is there some way I can do this?

like image 509
Nicholas Montaño Avatar asked Sep 14 '15 11:09

Nicholas Montaño


2 Answers

This question has a subtle "no but yes" kind of answer, which requires going into three concepts:

  1. Qualified names vs. unqualified names
  2. Modules and imports
  3. Aliasing

Point 1: every definition in Haskell has both a short, unqualified name like map, and a long, qualified name like Data.List.map.

Point 2: when you import a module into another, you can do either a qualified or an unqualified import. When you use unqualified import, the foreign module's names that you bring in will be aliased under their short names. When you do a qualified import, they will only be available under a modified name:

import qualified Data.Map as Map

Now in the module where this appeared, the Data.Map.map function is visible under the alias Data.map.

Third point: this means that every Haskell definition has a fully qualified name determined by its short name and the module where it's defined, but also unqualified or partially qualified aliases in each module where it is imported.

Now, your question has two answers:

  1. Two different classes cannot have methods that share the same fully qualified name. So if you define your Foo and Bar classes in the same module, that will fail.
  2. Two different classes can have methods that share the same unqualified name, as long as their fully qualified names are different—i.e., they're defined in different modules. To use both within one client module, however, you will need at least one qualified import so the aliases from the import don't clash.
like image 146
Luis Casillas Avatar answered Oct 23 '22 03:10

Luis Casillas


No, you cannot, at least within the same module. You can declare class Foo and class Bar in two different modules and import each of them into the same file, but you'll still have to qualify at least one of those imports to avoid conflicts.

like image 45
Nicholas Montaño Avatar answered Oct 23 '22 01:10

Nicholas Montaño