gpt4 book ai didi

f# - 传递解析为多种类型的通用函数的最佳方法是什么

转载 作者:行者123 更新时间:2023-12-03 10:07:12 28 4
gpt4 key购买 nike

背景:这是功能性 DI 的一种变体。关注 Scott's post我写了一个解释器。不同之处在于,我的解释器是通用的,并且根据您输入的内容进行了参数化。

出于测试目的,我想通过另一个解释器,这就是问题所在 - 我该怎么办?这是问题的简化大纲:

let y f =
let a = f 1
let b = f 2L
(a,b)
f是我的通用解释器,但在这里它显然受到第一次使用 int -> 'a 的限制.
在这个简化的场景中,我可以只传递解释器两次,但在我的实际实现中,类型空间相当大(基本类型 x3 输出类型)。

是否有一些 F# 机制可以让我这样做,而无需太多开销?

最佳答案

请看Crates .
这是一个简短的片段,描述了您想要完成的关键。我相信这个片段很有值(value),因为它有助于教会我们如何通过使用数学语言正式推理使用 F# 和其他 ML 类型系统。换句话说,它不仅向您展示了如何工作,而且还教会了您工作原理的深层原理。

The issue here is that we have reached a fundamental limitation of what is directly expressible in F#. It follows that the trick to simulating universal quantification is, therefore, to avoid ever passing the function around directly, instead hiding the type parameter away such that it cannot be fixed to one particular value by the caller, but how might one do that?

Recall that F# provides access to the .NET object system. What if we made our own class (in the object-oriented sense) and put a generic method on that? We could create instances of that which we could pass around, and hence carry our function with it (in the form of said method)?

// Encoding the function signature...
// val id<'a> : 'a -> 'a
// ...in terms of an interface with a single generic method
type UniversalId = abstract member Eval<'a> : 'a -> 'a

Now we can create an implementation which we can pass around without the type parameter being fixed:

// Here's the boilerplate I warned you about.
// We're implementing the "UniversalId" interface
// by providing the only reasonable implementation.
// Note how 'a isn't visible in the type of id -
// now it can't be locked down against our will!
let id : UniversalId =
{ new UniversalId with
member __.Eval<'a> (x : 'a) : 'a = x
}

Now we have a way to simulate a universally quantified function. We can pass id around as a value, and at any point we pick a type 'a to pass to it just as we would any value-level argument.

EXISTENTIAL QUANTIFICATION

There exists a type x, such that…

An existential is a value whose type is unknown statically, either because we have intentionally hidden something that was known, or because the type really is chosen at runtime, e.g. due to reflection. At runtime we can, however, inspect the existential to find the type and value inside.

If we don’t know the concrete type inside an existentially quantified type, how can we safely perform operations on it? Well, we can apply any function which itself can handle a value of any type – i.e. we can apply a universally quantified function!

In other words, existentials can be described in terms of the universals which can be used to operate upon them.


这种技术非常有用,它用于数据类型通用编程库 TypeShape,它允许您废弃您的样板 .NET 反射代码,以及用于“打包存在数据类型”的 MBrace 和 FsPickler。参见 Erik Tsarpalis 的 slides on TypeShape有关“在 .NET 中编码安全存在解包”和在 .NET 中编码 rank-2 类型的更多信息。
像 TypeShape 这样的反射助手库也应该直观地涵盖大多数(如果不是全部)用例:依赖注入(inject)需要在底层实现服务定位,因此 TypeShape 可以被认为是构建依赖注入(inject)的“原始组合库”。查看以 Arbitrary Type Shapes 开头的幻灯片: 特别要注意 Code Lens 数据类型:
type Lens<'T,'F> =
{
Get : 'T -> 'F
Set : 'T -> 'F -> 'T
}
最后,想了解更多想法,您可以阅读 Don Stewart 的博士论文 Dynamic Extension of Typed Functional Languages .

We present a solution to the problem of dynamic extension in staticallytyped functional languages with type erasure. The presented solution retainsthe benefits of static checking, including type safety, aggressive optimizations, and native code compilation of components, while allowingextensibility of programs at runtime.

Our approach is based on a framework for dynamic extension in a staticallytyped setting, combining dynamic linking, runtime type checking,first class modules and code hot swapping. We show that this frameworkis sufficient to allow a broad class of dynamic extension capabilities in anystatically typed functional language with type erasure semantics.

Uniquely, we employ the full compile-time type system to perform runtimetype checking of dynamic components, and emphasize the use of nativecode extension to ensure that the performance benefits of static typingare retained in a dynamic environment. We also develop the concept offully dynamic software architectures, where the static core is minimal andall code is hot swappable. Benefits of the approach include hot swappablecode and sophisticated application extension via embedded domain specificlanguages.


下面是一些粗粒度的设计模式,唐为 future 的工程师提供了遵循:
  • 第 3.6.3 节:专门化模拟器方法。
  • 演示如何将程序特化技术应用于聚合物化学的蒙特卡罗模拟。这种方法演示了如何“注入(inject)”专门的代码来解决所谓的“窥孔优化”。


  • 以及帮助构建“可扩展性之塔”的总图:
    Don Stewart's framework for dynamic extension of typed functional languages

    关于f# - 传递解析为多种类型的通用函数的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42598677/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com