Can two different classes have the same method names?

Let's pretend that

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

and want to do

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

which has the name of the overlap method, (++=) . Is there any way to do this?

+6
source share
3 answers

This question has a subtle answer "no, but yes", which requires a transition to three concepts:

  • Qualified Names vs. Unqualified Names
  • Modules and Import
  • Distortions

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

Point 2: when importing a module into another, you can perform qualified or unskilled import. When you use unqualified imports, the names of the external modules you enter will be aliases under their short names. When you perform qualified import, they will be available only under the changed name:

 import qualified Data.Map as Map 

Now in the module where it 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 defined by its short name and the module where it is defined, as well as unqualified or partially qualified aliases in each module where it is imported.

Now your question has two answers:

  • Two different classes cannot have methods that have the same fully qualified name. Therefore, if you define your Foo and Bar classes in the same module, this will not work.
  • Two different classes may have methods that have the same unqualified name if their fully qualified names are different, i.e. they are defined in different modules. However, for use as inside one client module, you will need at least one qualified import so that aliases from the import do not collide.
+2
source

No, you cannot, at least in 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 to prevent conflicts, you still have to qualify at least one of these imports.

+4
source

The following compilation without errors:

Main.hs:

 module Main where import qualified Foo import Bar instance Foo.Foo Char where c1 ++= c2 = c1 instance Bar Char where f ++= c = fc main = do putStrLn $ [ 'a' Foo.++= 'b' ] 

Foo.hs:

 module Foo where class Foo a where (++=) :: a -> a -> a 

Bar.hs:

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

In other words, we don’t need to refer to ++= using its full name inside the instance declaration, but when using inside main we need to indicate in which ++= we are talking about. In the instance declaration, we have already defined the scope for ++= , and main didn’t know which one they belonged to if we used unskilled imports. Therefore, if all we wanted to do was define class instances, then we would not need qualified imports.

0
source

All Articles