Why can't i re-use same value constructor among different data types?

前端 未结 2 1722
说谎
说谎 2021-01-18 01:00

i am new to Haskell and probably missing something really basic here, but i am not able to re-use same value constructor among different data types.

data Co         


        
相关标签:
2条回答
  • 2021-01-18 01:21

    There is no particular reason, that is how language was designed. I think the idea was to make sure compiler can infer type for as many expressions as possible. Note that if language will allow to reuse constructors, then you'll have to specify type for show Orange expression - compiler can't infer it anymore. Though now a lot of people don't take this reason seriously, and a lot of modern language extentions do break compiler's ability to infer types for many expressions. So I guess in few years you'll find that your example works already :)

    0 讨论(0)
  • 2021-01-18 01:25

    As a quick exercise try just defining one of your data types and then opening up GHCi to inspect it.

    data Colour = Red | Pink | Orange | Yellow
    

    If you use :t in GHCi, it will tell you the type of anything.

    > :t Red
    Red :: Colour
    > :t Orange 
    Orange :: Colour 
    

    So this tells you that your data constructor Orange is really just a function that takes no arguments and produces a value of type Colour.

    So what happens if you add a duplicate declaration?

    data Colour = Red | Pink | Orange | Yellow
    data Fruit  = Apple | Orange | Banana
    

    Now you have defined a function Orange that takes no arguments and produces a value of type Colour or a value of type Fruit. This won't work at all! It would be the same as defining your own custom function foo and giving it multiple type signatures:

    foo :: Int 
    foo :: String
    foo = "6"
    

    Which obviously doesn't work either.

    To get around this, you can define each data type in its own module, and use a qualified import to scope them correctly:

    import qualified Colour as C -- Module Colour.hs 
    import qualified Fruit as F -- Module Fruit.hs 
    
    orange1 = C.Orange :: C.Colour 
    orange2 = F.Orange :: F.Fruit
    

    Now, you might be thinking "The compiler is smart, it should know what Orange I'm talking about when I'm using it." and you'd be partially right. There is an ongoing effort to bring Overloaded or Duplicate record fields into Haskell. There are various other questions of that ilk already defined here, but I'll list a few references for further reading.

    • Why DuplicateRecordFields cannot have type inference?
    • https://github.com/adamgundry/ghc-proposals/blob/overloaded-record-fields/proposals/0000-overloaded-record-fields.rst
    • https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/DuplicateRecordFields
    0 讨论(0)
提交回复
热议问题