9

I'm confused about the arrow and what it actually means in the data constructor. I'm surprised it even compiled but I have no idea how to use it.

If I try to use it as the name of a data constructor it doesn't parse, and I'm not sure how else to interpret it. If I interpret it as a function type then the data constructor has no name which also does not make sense to me.

data Type
  = TBool
  | TInt
  | Arrow Type Type
  | (->) Type Type

test :: Type 
test = Arrow TBool TInt -- Ok

test' :: Type
test' = (->) TBool TInt -- Parse Error on input '->'
Mat
  • 202,337
  • 40
  • 393
  • 406
bobluza
  • 131
  • 1
  • 3
  • Are there any language extensions in use? – John F. Miller Jul 26 '19 at 04:41
  • 4
    That is _really_ weird. I can confirm that the `data` declaration parses, but attempting to use `(->)` fails, without enabling any extensions. I suspect that the parsing algorithm has different rules in a `data` declaration than in an expression, but can’t say anything definitively. – bradrn Jul 26 '19 at 05:17
  • 4
    This looks like a GHC bug to me. – chi Jul 26 '19 at 07:43
  • 2
    Pretty sure `data Type = (->) Type Type` _shouldn't_ parse. Infix constructors must generally start with a `:`, i.e. `data Type = (:->) Type Type` would be the closest legal approximation. – leftaroundabout Jul 26 '19 at 08:50
  • I am using overloaded strings and lambda case, but I don't think that is relevant here. @bradrn Indeed, test' does not parse. Should I just treat this syntax as a bug then? – bobluza Jul 26 '19 at 09:56
  • @leftaroundabout I think you're right, I was looking a little bit and concluded in the same – developer_hatch Jul 26 '19 at 14:29
  • 2
    I've submitted this as [issue #16999](https://gitlab.haskell.org/ghc/ghc/issues/16999). – K. A. Buhr Jul 27 '19 at 17:15
  • Infix constructors! Infix constructors! How did I miss infix constructors? – Gregory Higley Aug 02 '19 at 18:24

2 Answers2

2

It does look like a GHC bug (thanks to Kevin Buhr for reporting it) in the use case you provided.

Note

This does fail to parse with GADTs:

data Type where
  TBool :: Type
  TInt :: Type
  Arrow :: Type -> Type -> Type
  (->) :: Type -> Type -> Type
lehins
  • 9,642
  • 2
  • 35
  • 49
  • I doubt your hypothesis about the cause of the bug is right. See the discussion on the ticket. – dfeuer Aug 02 '19 at 15:32
  • 1
    @dfeuer, yep, my guess was off. In fact I still don't understand what is the reason for this bug. Nevertheless, the answer is still right, it is a ghc bug. ;) – lehins Aug 02 '19 at 18:15
  • I dunno either. Parsing Haskell is relatively hard, and parsing GHC Haskell is really hard. I personally think some of the decisions about syntax were unwise. It's pretty tricky to go back and change things in a mature language, but it looks like a few of those decisions are being reconsidered along the long road to `DependentHaskell`. – dfeuer Aug 02 '19 at 19:04
0

As @leftaroundabout commented, and According to this you must add a : in order to create infix constructors: And according to this question:

Unlike data constructors, infix type constructors are not allowed (other than (->)).

So by example this won't work:

data Type
  = TBool
  | TInt
  | Arrow Type Type
  | (-**) Type Type

test :: Type 
test = Arrow TBool TInt -- Ok

test' :: Type
test' = (-**) TBool TInt

but this will:

data Type
  = TBool
  | TInt
  | Arrow Type Type
  | (:-**) Type Type

test :: Type 
test = Arrow TBool TInt -- Ok

test' :: Type
test' = (:-**) TBool TInt

and this:

data Type
  = TBool
  | TInt
  | Arrow Type Type
  | (:-*) Type Type

test :: Type 
test = Arrow TBool TInt -- Ok

test' :: Type
test' = (:-*) TBool TInt

and in your case you will want something like:

data Type
  = TBool
  | TInt
  | Arrow Type Type
  | (:->) Type Type

test :: Type 
test = Arrow TBool TInt -- Ok

test' :: Type
test' = (:->) TBool TInt
developer_hatch
  • 15,898
  • 3
  • 42
  • 75