7

I'm trying to deriving Show, Eq, Ord etc in Idris, but none of the following trials works:

trail #1:

data Expr =
      Lit Int
    | Neg Expr
    | Add Expr Expr
    deriving (Show)

got:

deriving.idr:5:15-18:
  |
5 |     deriving (Show)
  |               ~~~~
When checking type of Main.Add:
Type mismatch between
        Type -> Type (Type of Show)
and
        Type (Expected type)

trail #2:

data Expr =
      Lit Int
    | Neg Expr
    | Add Expr Expr
    deriving (Show _)

got:

*deriving> Lit 1
Lit 1 : Expr
*deriving> Add (Lit 1) (Lit 1)
(input):Can't infer argument ty to Add, Can't infer argument deriving to Add

trail #3:

data Expr =
      Lit Int
    | Neg Expr
    | Add Expr Expr
    deriving (Show Expr)

got:

*deriving> Lit 1
Lit 1 : Expr
*deriving> Add (Lit 1) (Lit 1)
(input):Can't infer argument deriving to Add

I have searched the keyword deriving on http://docs.idris-lang.org/ and google, and even in the idris-dev repo under test/ directory, but there is no demo for the usage of deriving in idris. Anyone can help?

luochen1990
  • 3,689
  • 1
  • 22
  • 37
  • 4
    There is no `deriving` syntax. There is only elaborator reflection, which is like Template Haskell. – HTNW Jun 21 '18 at 23:34
  • @HTNW but the weird thing is when I'm trying to use the `deriving` syntax, it passed the syntax checking, so I think there must be something similar ? – luochen1990 Jun 22 '18 at 01:49
  • 3
    It's parsed as data `Expr = ... | Add (Expr) (Expr) (deriving) (Show)`, where `deriving` is just a (existential) type variable. You get an error because constructor field types must be `Type`s, but `Show` isn't. If you remove the `Show` "field" you get a constructor `Add : {deriving : Type} -> Expr -> Expr -> deriving -> Expr` – HTNW Jun 22 '18 at 02:04
  • @HTNW Oh, that explains everything... I'm still wondering how to use elaborator reflection to do the same thing as deriving, is there any document? – luochen1990 Jun 22 '18 at 02:07
  • There's the [documentation on the mechanism itself](http://docs.idris-lang.org/en/latest/reference/elaborator-reflection.html#elaborator-reflection), and there's [this (bitrotten?) library](https://github.com/david-christiansen/derive-all-the-instances) that implements some classes. It seems you'll have to put in a bit of work for this. – HTNW Jun 22 '18 at 02:20
  • 1
    @HTNW So there is no corresponding handy feature in Idris yet? – luochen1990 Jun 22 '18 at 04:55
  • 1
    Correct: there isn’t. – HTNW Jun 22 '18 at 10:43

1 Answers1

1

You can use Stefan Hoeck's idris2-sop library to generate implementations with elaborator reflection.

michaelmesser
  • 3,601
  • 2
  • 19
  • 42