什么是“monadic反射”?

时间:2010-02-22 13:08:45

标签: f#

什么是“monadic反射”?

如何在F#-program中使用它?

术语“反射”的含义是否与.NET反射相同?

3 个答案:

答案 0 :(得分:8)

Monadic反射本质上是用于描述分层monad或monad分层的语法。在Haskell中,描述也意味着构建monad。这是一个更高级别的系统,所以代码看起来像功能,但结果是monad组合 - 意味着如果没有实际的monad(它们是无功能的),那么在一天结束时没有任何真实/可运行的东西。菲林斯基最初试图将一种monad仿真用于Scheme,但更多的是探索monad的理论方面。

评论更正 - F#有Monad等效名为"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声称受到Filinski的启发

答案 1 :(得分:3)

我读了第一篇Google热门文章,其中有一些幻灯片:

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

从这看起来像

  1. 这与.NET反射不同。该名称似乎是指将数据转换为代码(反之亦然,具有具体化)。
  2. 代码使用标准的纯功能操作,因此在F#中应该很容易实现。 (一旦你明白了)
  3. 我不知道这对于为递归函数实现不可变缓存是否有用。看起来您可以定义可变操作并自动将它们转换为等效的不可变操作?我真的不明白幻灯片。
  4. Oleg Kiselyov也有an article,但我甚至没有尝试阅读它。还有一篇来自Jonathan Sobel(等)的论文。命中5是这个问题,所以我不再照顾它了。

答案 2 :(得分:1)

如前面的答案链接所述,Monadic reflectionbridge call/cc style and Church style programming的概念。更多地描述这两个概念:

使用自定义构建器类型创建

F# Computation expressions(= monads)。

Don Syme有一个很好的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。

F#具有部分功能应用,但它也是强类型的并且具有值限制 但OCaml没有价值限制。

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

// 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)

这里,零是一个函数,它将两个函数作为参数:f应用零次,因此这表示数字为零,x用于其他计算中的函数组合(如add)。 succ函数就像plusOne所以one = zero |> Plusone精选。

要执行这些函数,最后一个函数将使用last参数(x)调用其他函数为空。

(Haskell式编程。)

在F#中,限制值很难。 Church numerals can be made with C# 4.0 dynamic keyword(里面使用.NET反射)。我认为在F#中还有相同的解决方法。