在Idris中,“Eq a”是一种类型,我可以为它提供一个值吗?

时间:2017-06-03 02:12:25

标签: typeclass idris

在下文中,example1是标准语法(如文档所述),Eq a作为约束。在example2中,我直接指定Eq a作为参数的类型,编译器接受它。但是,我不清楚我可以指定哪种类型的值。对于特定类型a,例如Nat,我认为以某种方式指定Eq Nat的实现是有意义的,无论是默认实现还是其他一些命名实现。

%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

造成漏洞:

- + 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

据我所知,我实际上不能将example2b用作函数,除非我有办法为类型为Eq a的第二个参数指定值。

在某些情况下,能够将接口约束应用于参数的值(而不是参数的类型)会非常有用,所以我希望这是Idris的有效功能

1 个答案:

答案 0 :(得分:5)

您可以使用命名实现:

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

命名实现的一个有用的应用是定义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

评论:获取默认实例

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

然后你可以拥有你的默认实例:

getEq (List Nat) -- => implementation of Eq...