可以ML仿函数在.NET(C#/ F#)完全编码?(Can ML functors be fully

2019-07-18 02:08发布

可以ML仿函数与.NET接口和泛型被实际表现? 是否有违抗这种编码先进的ML仿函数使用的例子吗?

答案汇总

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

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

实用的编码需要妥协,如半安全向下转换。 您的里程将持谨慎态度。

博客和代码:

  1. blog.matthewdoig.com
  2. higherlogics.blogspot.com
  3. 单子算符,F#

Answer 1:

其中之一的ML模块的主要功能是分享规范。 有没有在.NET中没有机制,能够模拟它们 - 所需的机器是太不同。

您可以尝试通过关闭共享类型分为参数做到这一点,但这并不能如实地模仿定义签名的能力,然后再应用共享,也许在多种不同的方式。

在我看来,.NET将受益于东西,确实有这样的机器 - 那就更接近真正支持现代语言的多样性。 希望包括模块的系统像那些在MixML,这在我看来是模块系统的未来更多的最新进展。 http://www.mpi-sws.org/~rossberg/mixml/



Answer 2:

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; }; }
  }
}

正如你所看到的,演员大多是安全的,因为该类型系统保证了品牌的表达式类型的品牌诠释者相匹配。 要搞砸的唯一方法,就是如果客户端创建了自己的精通等级和指定解释品牌。 有这太避免这一问题的安全编码,但它远远普通程序太烦琐。

后来我用这个编码和翻译的例子从写在MetaOCaml奥列格的一篇论文中,使用C#和LINQ。 解释器可以透明地运行在ASP.NET中使用该语言的嵌入式服务器端或客户端如JavaScript编写的程序。

这种抽象了口译是Oleg的最终无标签编码的功能。 在博客文章中提供链接到他的论文。

接口在.NET一流的,因为我们使用的接口编码模块签名,模块和模块的签名也是这个编码一流。 因此,简单地函子来代替模块签名,即直接使用的接口。 他们将接受ISymantics <B>的一个实例,并委派给它的任何呼叫。



Answer 3:

我不知道ML仿函数足够好,真正回答你的问题。 但是,我会说我总是与一元编程找到的.Net的一个限制因素是不能在抽象“M”中的意义上的“的forall M. 具有M某种类型的表达<T>”(例如,其中M是一种类型的构造函数(类型需要一个或多个通用参数))。 所以,如果这是你有时需要/用仿函数使用的东西的话,我觉得非常有信心有表达它的.Net没有什么好办法。



Answer 4:

我现在已经发布了详细的描述我的翻译ML模块,签名和函子的一个等价的C#编码。 我希望有人发现它是有用的。



Answer 5:

Brian的评论是即期。 下面是一个使用仿函数,得到(严格)实现的Haskell OCaml的代码sequence :: (Monad m) => [ma] -> m [a]参数化对有关单子:

module type Monad = 
sig
  type 'a t (*'*)
  val map : ('a -> 'b) -> ('a t -> 'b t)
  val return : 'a -> 'a t
  val bind : 'a t -> ('a -> 'b t) -> 'b t
end

module type MonadUtils =
sig
  type 'a t (*'*)
  val sequence : ('a t) list -> ('a list) t
end

module MakeMonad (M : Monad) : MonadUtils =
struct
  type 'a t = 'a M.t
  let rec sequence = function
    | [] -> 
        M.return []
    | x :: xs ->
        let f x = 
          M.map (fun xs -> x :: xs) (sequence xs)
        in 
          M.bind x f
end

这看起来具有挑战性的.NET来表达。

更新

通过使用技术naasking我能够编码可重复使用的sequence在F#功能的主要类型安全的方式(采用向下转换)。

http://gist.github.com/192353



文章来源: Can ML functors be fully encoded in .NET (C#/F#)?
标签: .net f# functor