命名为v未命名的数据类型参数

时间:2016-08-27 00:45:50

标签: idris

Type Driven Development with Idris第6章的代码中,我对这段代码感到困惑:

data DataStore : Type -> Type where
    MkData : (size : Nat) ->
             (items : Vect size schema) ->
             DataStore schema

我认为它可能无法编译,因为schema似乎未定义或至少需要以某种方式绑定到DataStore的第一个参数。但是,它加载很好,可以这样使用:

*DataStore> the (DataStore String) $ MkData 2 ["Fred", "Wilma"]
MkData 2 ["Fred", "Wilma"] : DataStore String

我认为DataStore的第一个参数需要像schema这样命名:

data DataStore : (schema : Type) -> Type where
    MkData : (size : Nat) ->
             (items : Vect size schema) ->
             DataStore schema

此定义可以与初始定义类似地使用。

我想知道两个定义之间是否存在任何语义差异,以及是否有人可以帮助我解释我对schema未定义的错误直觉。

1 个答案:

答案 0 :(得分:4)

这里发生了两件事。第一个是隐含的论点。用作函数参数的小写名称始终转换为隐式参数。例如,函数组合运算符:

Idris> :t (.)
(.) : (b -> c) -> (a -> b) -> a -> c
Idris> :set showimplicits 
Idris> :t (.)
Prelude.Basics.(.) : {c : Type} -> {a : Type} -> {b : Type} -> (b -> c) -> (a -> b) -> a -> c

compose的类型涉及变量a,b和c,它们在类型签名中的任何地方都没有声明。伊德里斯将它们变成隐含的参数 - 所有这些参数都具有类型Type - 它将尝试通过统一来推断。 {curly brackets}是显式指定隐式参数的语法。您始终可以在解释器中使用:set showimplicits来查看它们。在DataStore示例中,schema是隐式变量。

当您调用包含它们的函数时,您也可以指定implicits:

λΠ> MkData {schema = String} 2 ["hi", "Steven"]
MkData 2 ["hi", "Steven"] : DataStore String

第二件事是data声明中类型构造函数类型中的变量不限于除该类型构造函数之外的任何内容。你给出的DataStore的第二个定义与原始定义完全相同,因为&#34; schema&#34; DataStore : (schema : Type) -> TypeMkData的类型签名范围内不在using System.Windows; namespace YourNameSpace { /// <summary> /// Add Proxy <ut:BindingProxy x:Key="Proxy" Data="{Binding}" /> to Resources /// Bind like <Element Property="{Binding Data.MyValue, Source={StaticResource Proxy}}" /> /// </summary> public class BindingProxy : Freezable { protected override Freezable CreateInstanceCore() { return new BindingProxy(); } public object Data { get { return (object)GetValue(DataProperty); } set { SetValue(DataProperty, value); } } public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy)); } }