【问题标题】:Functional Programming: Embedding functions in AST?函数式编程:在 AST 中嵌入函数?
【发布时间】:2018-05-19 03:53:41
【问题描述】:

我目前正在尝试使用 F# 将链接函数建模为 AST 的一部分(尽管目前它更像是一个链)。每个环节都是一个功能,它也可能附有一条链。但是,要指定附加到链接的链的类型签名,您还必须添加更多类型参数。但是你这样做了,然后又添加了一个参数,等等,无穷无尽。下面是一个例子。

type Chain<'a, 'b, 'c> =
| Link of ('a -> 'b) * Chain<'c>  // This doesn't work - you need more type params supplied
| End  of 'a

我希望能够将链表示为 Link ((fun x -&gt; x + 5), Link... 等,直到它到达 End,但我无法在不遇到类型爆炸问题的情况下这样做。

如果有人能指出一个有助于创建任意长度的任意函数链的方向,我将不胜感激。

【问题讨论】:

  • 完全不清楚你想做什么以及阻止你做的事情。请尝试澄清问题。

标签: function f# functional-programming abstract-syntax-tree


【解决方案1】:

虽然这个问题有点不清楚,但我认为你所要求的更像是(假设语法):

type Chain<'a> =
| Link of ('b -> 'a) * Chain<'b>
| End of 'a

我们引入了一个新的类型参数'b insideLink 的情况——它可以是任何类型,只要函数的域与嵌套 @ 的类型参数匹配987654325@。这与“存在类型”的概念(基本上是泛型的通用类型量化的双重概念)有关。

坏消息:在 F# 中没有简单的语法来实现这一点。 好(?)消息:如果你真的想的话,有一种非常丑陋的编码方式。

结果是,如果你想表达你的链接类型的想法,你可以通过机械的方式引入一些辅助类型来实现(类型∃'t.F&lt;'t&gt;可以编码为∀'x.(∀'t.F&lt;'t&gt; -&gt; 'x) -&gt; 'x,可以用 F# 类型系统表示)。

这是您的示例在此编码下的样子:

type 'a Chain =
| End of 'a
| Link of SomeLink<'a>
and SomeLink<'a> = abstract Apply : LinkUser<'a,'x> -> 'x
and LinkUser<'a,'x> = abstract Apply : ('b -> 'a) * Chain<'b> -> 'x

let mkLink (f, c) = Link { new SomeLink<_> with member __.Apply(w) = w.Apply(f, c) }

let chain = mkLink (sprintf "%i", End 1)

let rec applyChain<'a> : 'a Chain -> 'a = function
| End a -> a
| Link l -> l.Apply { new LinkUser<_,_> with member __.Apply(f, c) = f (applyChain c) }

applyChain chain // "1"

【讨论】:

  • 谢谢,存在类型似乎确实是我正在寻找的东西,大致。但是,我对数学符号或“泛型通用类型量化的双重概念”不是很熟悉。我可以要求澄清这些观点吗?
  • 通用类型量词是指forall量词;在混合数学/F# 表示法中,这类似于∀'x.F&lt;'x&gt;,表示可以在类型F&lt;'x&gt; 上用于所有类型'x 的值;在 F# 中,这实际上是泛型函数或方法为您提供的。有关二元性的更多信息,请参阅Wikipedia
猜你喜欢
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
  • 1970-01-01
相关资源
最近更新 更多