haskell sum type multiple declaration error

前端 未结 4 1297
情歌与酒
情歌与酒 2020-12-22 03:55
data A=A
data B=B
data AB=A|B

Which makes a sum type AB from A and B.

but the last line induces a compile error \"multiple declarations of

相关标签:
4条回答
  • 2020-12-22 04:27

    Sum types have to be tagged. a+a has to have two injections from a.

    To understand how algebraic data types work, take a simple example:

    data X = A | B C
    

    This defines a new type constructor, X, along with data constructors A and B. The B constructor takes/holds an argument of type C.

    The primary canonical sum type in Haskell is Either:

    data Either a b = Left a | Right b
    
    0 讨论(0)
  • 2020-12-22 04:38

    Because the type of the value created using data constructor A or B will be ambiguous. When I have a = B for instance, what is the type of a? It is A or AB?

    You should consider using different data constructor as follows:

    data A = MkA
    data B = MkB
    data AB = A A | B B
    
    0 讨论(0)
  • 2020-12-22 04:41

    When you say data AB = A | B, you are not referring to the types A and B, but rather are defining data constructors A and B. These conflict with the constructors defined on the the previous lines.

    If you want to create a type AB that is the sum of A and B, you must provide data constructors that wrap the types A and B, e.g.:

    data AB = ABA A | ABB B
    
    0 讨论(0)
  • 2020-12-22 04:48

    You're getting fooled. You think when you write data A=Int|Bool that you are saying that a value of type A can be a value of type Int or a value of type Bool; but what you are actually saying is that there are two new value-level constructors named Int and Bool, each containing no information at all, of type A. Similarly, you think that data AB=A|B says you can either be of type A or type B, but in fact you are saying you can either have value A or value B.

    The key thing to keep in mind is that there are two namespaces, type-level and term-level, and that they are distinct.

    Here is a simple example of how to do it right:

    data A=A
    data B=B
    data AB=L A|R B
    

    The last line declares two new term-level constructors, L and R. The L constructor carries a value of type A, while the R constructor carries a value of type B.

    You might also like the Either type, defined as follows:

    data Either a b = Left a | Right b
    

    You could use this to implement your AB if you wanted:

    type AB = Either A B
    

    Similarly, you could use Either Int Bool for your tagged union of Int and Bool.

    0 讨论(0)
提交回复
热议问题