Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Idris, is "Eq a" a type, and can I supply a value for it?

In the following, example1 is standard syntax (as documented), with Eq a as a constraint. In example2, I specify Eq a directly as the type of a parameter, and the compiler accepts it. However it is unclear what I can specify as a value of that type. For a specific type a, eg Nat, I assume it would make sense to somehow specify an implementation of Eq Nat, either the default implementation, or some other named implementation.

%default total

example1: Eq a => (x : a) -> (y : a) -> Type
example1 {a} x y = ?example1_rhs

example1b: Eq a => (x : a) -> (y : a) -> Type
example1b {a} x y = x == y = True

example2: (a : Type) -> Eq a -> (x : a) -> (y : a) -> Type
example2 a eqa x y = ?example2_rhs

example2b: (a : Type) -> Eq a -> (x : a) -> (y : a) -> Type
example2b a eqa x y = x == y = True

eq_nat : Eq Nat
eq_nat = ?eq_nat_rhs

example_of_example2 : Type
example_of_example2 = example2 Nat eq_nat 3 3

Resulting holes:

- + Main.example1_rhs [P]
 `--                  a : Type
                      x : a
                      y : a
             constraint : Eq a
     --------------------------
      Main.example1_rhs : Type

- + Main.example2_rhs [P]
 `--                  a : Type
                    eqa : Eq a
                      x : a
                      y : a
     --------------------------
      Main.example2_rhs : Type

- + Main.eq_nat_rhs [P]
 `-- Eq Nat

As far as I can tell, I can't actually use example2b as a function unless I have some way to specify a value for the second parameter of type Eq a.

There are situations where it would be genuinely useful to be able to apply an interface constraint to the value of a parameter (as opposed to the type of a parameter), so I'm hoping that this is a valid feature of Idris.

like image 810
Philip Dorrell Avatar asked Jun 03 '17 02:06

Philip Dorrell


People also ask

How to declare constants in the Idris library?

There are also several data types declared in the library, including Bool , with values True and False. We can declare some constants with these types. Enter the following into a file Prims.idr and load it into the Idris interactive environment by typing idris2 Prims.idr:

What are types in Idris?

In Idris, types are first class, meaning that they can be computed and manipulated (and passed to functions) just like any other language construct. For example, we could write a function which computes a type:

How do you write a program in Idris?

When writing Idris programs both the order in which definitions are given and indentation are significant. Functions and data types must be defined before use, incidentally each definition must have a type declaration, for example see x : Int, foo : String, from the above listing.

What is qualified do notation in Idris?

Idris will, in general, try to disambiguate which operators you mean by type, but you can explicitly choose with qualified do notation, for example: The Prelude.do means that Idris will use the (>>=) and (>>) operators defined in the Prelude. Sometimes we want to pattern match immediately on the result of a function in do notation.


1 Answers

You could use named implementations:

[eq_nat] Eq Nat where { ... }
...
example_of_example2 : Type
example_of_example2 = example2 Nat eq_nat 3 3

A useful application of named implementations are defining multiple implementation of Monoid:

[PlusNatSemi] Semigroup Nat where
  (<+>) x y = x + y

[MultNatSemi] Semigroup Nat where
  (<+>) x y = x * y

[PlusNatMonoid] Monoid Nat using PlusNatSemi where
  neutral = 0

[MultNatMonoid] Monoid Nat using MultNatSemi where
  neutral = 1

To comment : To get the default instance

getEq : (a : Type) -> {auto inst : Eq a} -> Eq a
getEq a {inst} = inst

Then you can have your default instance:

getEq (List Nat) -- => implementation of Eq...
like image 62
Belleve Invis Avatar answered Oct 14 '22 01:10

Belleve Invis