ML仿函数可以用.NET完全编码(C#/ F#)吗?

t0y*_*yv0 17 .net f# functor

ML仿函数可以用.NET接口和泛型实际表达吗?是否有一个先进的ML仿函数使用示例来抵制这种编码?

答案摘要:

在一般情况下,答案是否定的.ML模块提供不直接映射到.NET概念的功能(例如通过签名共享规范[ 1 ]).

但是,对于某些用例,可以翻译ML习语.这些情况包括不仅基本Set函子[ 2 ],也单子[的函子编码3 ],和甚至更高级的Haskell的用途,如最后无代码解释器[ 4,5 ].

实用的编码需要妥协,例如半安全的低压.你的里程会很谨慎.

博客和代码:

  1. blog.matthewdoig.com
  2. higherlogics.blogspot.com
  3. F#中的monad仿函数

naa*_*ing 11

HigherLogics是我的博客,我花了很多时间来研究这个问题.这种限制确实是对类型构造函数的抽象,即"泛型泛型".模仿ML模块和仿函数似乎是最好的,至少需要一个(半安全)模型.

它主要归结为定义抽象类型,以及对应于在该类型上运行的模块签名的接口.抽象类型和界面共享一个类型参数B,我称之为"品牌"; 品牌通常只是实现模块接口的子类型.该品牌确保传入的类型是模块所期望的正确子类型.

// signature
abstract class Exp<T, B> where B : ISymantics<B> { }
interface ISymantics<B> where B : ISymantics<B>
{
  Exp<int, B> Int(int i);
  Exp<int, B> Add(Exp<int, B> left, Exp<int, B> right);
}
// implementation
sealed class InterpreterExp<T> : Exp<T, Interpreter>
{
  internal T value;
}
sealed class Interpreter : ISymantics<Interpreter>
{
  Exp<int, Interpreter> Int(int i) { return new InterpreterExp<int> { value = i }; }
  Exp<int, Interpreter> Add(Exp<int, Interpreter> left, Exp<int, Interpreter> right)
  {
    var l = left as InterpreterExp<int>; //semi-safe cast
    var r = right as InterpreterExp<int>;//semi-safe cast
    return new InterpreterExp<int> { value = l.value + r.value; }; }
  }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,演员表大多是安全的,因为类型系统确保表达式类型的品牌与解释器的品牌相匹配.解决这个问题的唯一方法是,如果客户创建自己的Exp类并指定Interpreter品牌.有一个更安全的编码可以避免这个问题,但它对于普通的编程来说太笨重了.

我后来使用这种编码并将 Oleg的一篇用MetaOCaml编写的论文中的例子翻译成了C#和Linq.解释器可以透明地运行在ASP.NET或客户端使用此嵌入式语言服务器端编写的程序作为JavaScript.

这种对解释器的抽象是Oleg最终无标记编码的一个特征.博客文章中提供了他论文的链接.

接口在.NET中是一流的,因为我们使用接口来编码模块签名,所以模块和模块签名在这种编码中也是一流的.因此,仿函数只是直接使用接口代替模块签名,即.他们会接受一个I​​Symantics <B>的实例并委托任何调用它.


Bri*_*ian 8

我不太清楚ML仿函数真的能回答你的问题.但我会说.我总是发现使用monadic编程的一个限制因素是无法在"forall M. 某种类型表达式与M <T> " 的意义上抽象"M "(例如,其中M是一种类型)构造函数(带有一个或多个泛型参数的类型)).所以,如果这是你有时需要/用仿函数使用的东西的话,我觉得非常有信心有表达它的.Net没有什么好办法.

  • 是的,我认为这被称为"更高级的多态性",我真的很想念Haskell.OCaml没有这个,但我见过OCaml库(JaneStreet Core)通过仿函数提供monad.我需要进一步调查这一点,看看它如何与F#一起玩 - 我不太了解仿函数...... (3认同)

RD1*_*RD1 6

ML模块的一个关键特性是共享规范..NET中没有能够模仿它们的机制 - 所需的机制就是太不同了.

您可以尝试通过将共享类型转换为参数来执行此操作,但这不能忠实地模拟定义签名的能力,然后可能以多种不同方式应用共享.

在我看来,.NET将从拥有这种机制的东西中受益 - 它将更接近于真正支持现代语言的多样性.希望包括模块系统的最新进展,如MixML中的模块系统,我认为模块系统的未来. http://www.mpi-sws.org/~rossberg/mixml/