Existential vs. Universally quantified types in Haskell

前端 未结 2 1805
北恋
北恋 2020-12-12 12:31

What exactly is the difference between these? I think I understand how existential types work, they are like having a base class in OO without a way to down cast. How are un

2条回答
  •  眼角桃花
    2020-12-12 12:40

    Bartosz Milewski in his book offers some good insight about why Haskell doesnt need an existential quantifier:

    in pseudo-Haskell:

    (exists x. p x x) -> c ≅ forall x. p x x -> c
    

    It tells us that a function that takes an existential type is equivalent to a polymorphic function. This makes perfect sense, because such a function must be prepared to handle any one of the types that may be encoded in the existential type. It’s the same principle that tells us that a function that accepts a sum type must be implemented as a case statement, with a tuple of handlers, one for every type present in the sum. Here, the sum type is replaced by a coend, and a family of handlers becomes an end, or a polymorphic function.

    Hence, an example of an existentially quantified type in Haskell is

    data Sum = forall a. Constructor a    (i.e. forall a. (Constructor_a:: a -> Sum) ≅ Constructor:: (exists a. a) -> Sum)
    

    which can be thought of as a sum data Sum = int | char | bool | .... In contrast, an example of a universally quantified type in Haskell is

    data Product = Constructor (forall a. a)
    

    which can be though of as a product data Product = int char bool ....

提交回复
热议问题