在下文中,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的有效功能
答案 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...