代码之家  ›  专栏  ›  技术社区  ›  Tuomas Hietanen

什么是“一元反射”?

f#
  •  14
  • Tuomas Hietanen  · 技术社区  · 15 年前

    如何在F程序中使用它?

    “反射”一词的含义与.NET反射相同吗?

    3 回复  |  直到 15 年前
        1
  •  8
  •   ZXX    14 年前

    一元反射本质上是描述分层单体或单体分层的语法。在Haskell中,描述也意味着构造单子。这是一个更高级别的系统,所以代码看起来像是功能性的,但是结果是monad组合——这意味着如果没有实际的monad(它们是非功能的),那么一天结束时就没有真正的/可运行的。菲林斯基这样做的初衷是试图给Scheme带来一种单子模拟,但更多的是为了探索单子的理论方面。

    "Computation Expressions"

    Filinski's paper at POPL 2010 -没有代码但有很多理论,当然还有他1994年的原始论文- Representing Monads . 加上一个有代码的: Monad Transformers and Modular Interpreters (1995年)

    Filinski's code 是在线的。我只列出一个步骤,看看另一个7和自述。也只是 a bit of F# code 据说是受到菲林斯基的启发

        2
  •  3
  •   Nathan Shively-Sanders    15 年前

    我通读了谷歌的第一个热门话题,一些幻灯片:

    http://www.cs.ioc.ee/mpc-amast06/msfp/filinski-slides.pdf

    从这个看来

    1. 代码使用标准的纯函数操作,因此在F#中实现应该很容易。(一旦你明白了)
    2. 我不知道这对于实现递归函数的不可变缓存是否有用。看起来你可以定义可变操作并自动将它们转换为等价的不可变操作?我不太懂幻灯片。

    Oleg Kiselyov也有 an article ,但我都没试着读。还有一份报纸 Jonathan Sobel (等)。第五题就是这个问题,所以我就不去管了。

        3
  •  1
  •   Tuomas Hietanen    13 年前

    Monadic reflection 是一个概念 bridge call/cc style and Church style programming

    F# Computation expressions (=monad)是用自定义生成器类型创建的。

    唐·赛姆有一个好的 blog post about this . 如果我编写代码来使用生成器并使用如下语法:

    attempt { let! n1 = f inp1
              let! n2 = failIfBig inp2 
              let sum = n1 + n2
              return sum }
    

    call/cc "call-with-current-continuation" 风格方案:

    attempt.Delay(fun () ->
      attempt.Bind(f inp1,(fun n1 ->
        attempt.Bind(f inp2,(fun n2 ->
          attempt.Let(n1 + n2,(fun sum ->
            attempt.Return(sum))))))))
    

    (方案式编程)


    F基于OCaml。


    OCaml可用于教会类编程,其中组合函数用于构造任何其他函数(或程序):

    // S K I combinators:
    let I x = x
    let K x y = x
    let S x y z = x z (y z)
    
    //examples:
    let seven = S (K) (K) 7
    let doubleI = I I //Won't work in F#
    // y-combinator to make recursion 
    let Y = S (K (S I I)) (S (S (K S) K) (K (S I I)))
    

    Church numerals 是用纯函数表示数字的一种方法。

    let zero f x = x
    //same as: let zero = fun f -> fun x -> x
    let succ n f x = f (n f x)
    let one = succ zero
    let two = succ (succ zero)
    let add n1 n2 f x = n1 f (n2 f x)
    let multiply n1 n2 f = n2(n1(f))
    let exp n1 n2 = n2(n1)
    

    为了执行这些函数,最后一个函数将调用最后一个参数(x)为null的其他函数。

    在F#值限制使得这很难实现。 Church numerals can be made with C# 4.0 dynamic keyword (内部使用.NET反射)。我认为在F中也有一些解决方法。