Jak*_*ell 6 typechecking idris
我只阅读了标准教程并且稍微摸了一下,所以我可能会遗漏一些简单的东西.
如果在Idris中无法做到这一点,请解释原因.此外,如果可以用另一种语言完成,请提供代码示例并解释有关该语言类型系统的不同之处.
这是我的方法.问题首先出现在第三部分.
v : List Nat
v = []
Run Code Online (Sandbox Code Playgroud)
这在REPL中编译并表现为[] : List Nat
.优秀.
emptyList : (t : Type) -> List t
emptyList t = []
v' : List Nat
v' = emptyList Nat
Run Code Online (Sandbox Code Playgroud)
不出所料,这是有效的v' == v
.
Ord
类的实例emptyListOfOrds : Ord t => (t : Type) -> List t
emptyListOfOrds t = []
v'' : List Nat
v'' = emptyListOfOrds Nat -- !!! typecheck failure
Run Code Online (Sandbox Code Playgroud)
最后一行失败,出现此错误:
When elaborating right hand side of v'':
Can't resolve type class Ord t
Run Code Online (Sandbox Code Playgroud)
Nat
是一个例子Ord
,那么问题是什么?我试图取代Nat
以s v''
与Bool
(不是实例Ord
),但有错误没有变化.
使Ord t
显式参数满足类型检查器吗?显然不是,但即使它确实要求呼叫者传递冗余信息也不理想.
emptyListOfOrds' : Ord t -> (t : Type) -> List t
emptyListOfOrds' a b = []
v''' : List Nat
v''' = emptyListOfOrds (Ord Nat) Nat -- !!! typecheck failure
Run Code Online (Sandbox Code Playgroud)
这次错误更详细:
When elaborating right hand side of v''':
When elaborating an application of function stackoverflow.emptyListOfOrds':
Can't unify
Type
with
Ord t
Specifically:
Can't unify
Type
with
Ord t
Run Code Online (Sandbox Code Playgroud)
我可能错过了一些关于如何根据类型声明检查值的关键见解.
正如其他答案所解释的那样,这是关于变量t
绑定的方式和位置.也就是说,当你写:
emptyListOfOrds : Ord t => (t : Type) -> List t
Run Code Online (Sandbox Code Playgroud)
详细说明者将看到't'在其使用时未Ord t
绑定,因此隐式绑定它:
emptyListOfOrds : {t : Type} -> Ord t => (t : Type) -> List t
Run Code Online (Sandbox Code Playgroud)
所以你真正想说的是有点像:
emptyListOfOrds : (t : Type) -> Ord t => List t
Run Code Online (Sandbox Code Playgroud)
哪个会在类型类约束之前绑定t,因此它Ord t
出现在范围内.不幸的是,不支持此语法.我认为没有理由不支持这种语法,但目前并非如此.
你仍然可以实现你想要的东西,但它很难看,我担心:
由于类是第一类,您可以将它们作为普通参数给出:
emptyListOfOrds : (t : type) -> Ord t -> List t
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用特殊语法%instance
在调用时搜索默认实例emptyListOfOrds
:
v'' = emptyListOfOrds Nat %instance
Run Code Online (Sandbox Code Playgroud)
当然,您并不是真的想在每个调用站点执行此操作,因此您可以使用默认隐式参数来为您调用搜索过程:
emptyListOfOrds : (t : Type) -> {default %instance x : Ord t} -> List t
v'' = emptyListOfOrds Nat
Run Code Online (Sandbox Code Playgroud)
如果没有明确给出其他值,default val x : T
语法将x
使用默认值填充隐式参数val
.给予%instance
作为缺省则是相当多到什么与阶级局限时会发生相同的,实际上我们很可能改变的执行Foo x =>
语法,做的正是这个......我觉得我做得不是唯一的原因是,default
论据不存在但是当我首先实现类型类时.