Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't constructors have required type arguments?

Let's say I define the following datatype:

data fmt :* (n :: Nat) where
    Rep :: fmt -> fmt :* n

Using RequiredTypeArguments, I can define a function that takes the n parameter as a required type argument:

(*:) :: fmt -> forall n -> fmt :* n
fmt *: n = Rep fmt

But if I try to do this directly in the datatype constructor, I get an error from GHC 9.10.1:

data a :* (n :: Nat) where
    (:*) :: a -> forall n -> a :* n
    • Illegal visible, dependent quantification in the type of a term
    • In the definition of data constructor ‘:*’
   |
83 |     (:*) :: a -> forall n -> a :* n
   |                  ^^^^^^^^^^^^^^^^^^

What makes (:*) be problematic vis-a-vis (*:)? What would break / what would be undecidable during typechecking if GHC accepted it?

like image 255
Cactus Avatar asked Sep 29 '25 10:09

Cactus


1 Answers

Disclaimer: I'm not sure if this is the true motivation, but it seems like one possible motivation.

If I could write 'a' :* 3 and 'b' :* 5, I think I'd expect to also be able to write something like

case x of
    'a' :* 3 -> ...
    'b' :* 5 -> ...
    _ -> ...

That seems problematic given that at runtime, 3 and 5 don't actually exist anywhere as chunks of data.

like image 144
Daniel Wagner Avatar answered Oct 02 '25 05:10

Daniel Wagner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!