Reflection 关于类型参数的思考

Reflection 关于类型参数的思考,reflection,idris,Reflection,Idris,我正在尝试创建一个函数 import Language.Reflection foo : Type -> TT 我用reflect策略进行了尝试: foo = proof { intro t reflect t } 但这反映在变量t本身上: *SOQuestion> foo \t => P Bound (UN "t") (TType (UVar 41)) : Type -> TT Idris中的反射是纯语法的、仅编译时的特性。要预测它将如何工

我正在尝试创建一个函数

import Language.Reflection
foo : Type -> TT
我用
reflect
策略进行了尝试:

foo = proof
  {
    intro t
    reflect t
  }
但这反映在变量
t
本身上:

*SOQuestion> foo
\t => P Bound (UN "t") (TType (UVar 41)) : Type -> TT

Idris中的反射是纯语法的、仅编译时的特性。要预测它将如何工作,您需要了解Idris如何将您的程序转换为其核心语言。重要的是,您将无法在运行时获得反射项并像使用Lisp一样重新构建它们。以下是您的程序的编译方式:

  • 在内部,Idris创建了一个孔,该孔的类型应为
    type->TT
  • 它在此状态下运行
    foo
    的校对脚本。我们从没有假设和类型
    type->TT
    的目标开始。也就是说,正在构造一个术语,它看起来像
    ?rhs:Type=>TT。rhs
    ?foo:ty=>body
    语法显示有一个名为
    foo
    的孔,其最终值将在
    body
    内部可用
  • 步骤
    intro t
    创建了一个参数为
    t:Type
    的函数-这意味着我们现在有了一个类似
    ?foo\u body:TT的术语\t:Type=>foo\u body
  • 然后,
    reflect t t
    步骤将右侧的术语转换为
    TT
    来填充当前孔。该术语实际上只是对函数参数的引用,因此得到变量
    t
    <代码>反射,与所有其他校对脚本步骤一样,只能访问编译时直接可用的信息。因此,用术语
    t
    的反射填充
    foo_body
    的结果是
    P绑定(UN“t”)(t类型(UVar(-1))
  • 如果您可以在这里做您想要做的事情,那么它将对理解Idris代码和高效运行Idris代码产生重大影响

    理解上的损失将来自于无法使用参数来根据函数类型推断函数的行为。所有函数都将有效地成为潜在的特殊多态性函数,因为它们可以(比如)在字符串列表上运行,而不是在int列表上运行

    性能损失将来自表示足够的类型信息来进行反射。编译Idris代码后,其中没有类型信息(与JVM或.NET等系统或Python等动态类型系统不同,在这些系统中,类型具有代码可以访问的运行时表示形式)。在Idris中,类型可能非常大,因为它们可以包含任意程序——这意味着需要维护更多的信息,在类型级别进行的计算也必须在运行时保留和重复

    如果您想在编译时对类型的结构进行进一步的自动化验证,请查看
    applytatic
    策略。它的参数应该是一个函数,它接受反映的上下文和目标,并返回一个新的反映的战术脚本。可以看到一个例子

    所以我想总结一下,Idris不能做你想做的事情,而且它可能永远也做不到,但你可以用另一种方式取得进展