【问题标题】:Partial Function Application in Concatenative Programming Languages级联编程语言中的偏函数应用
【发布时间】:2019-05-02 22:06:08
【问题描述】:

假设我有一个haskell 函数f n l = filter (n<) l,它接受一个整数n 并列出l 并返回l 中大于n 的所有整数。

我正试图弄清楚如何用 Joy 之类的语言最好地编写这个函数。我通常很幸运地将haskell 函数转换为无点形式f = filter . (<),然后尝试从那里用Joy 重写它。但我不知道如何用串联语言模拟部分函数应用程序。

到目前为止,我已经尝试过类似swap [[>] dip] filter 的操作,但似乎必须有更好/更简洁的方式来编写它。

另外,我正在尝试编写自己的连接语言,并且想知道惰性求值是否可以与连接语言兼容。

【问题讨论】:

  • 你的最后一句话对我来说似乎是一个完全不同的问题。考虑将其删除,并将其作为一个单独的问题提出。
  • @amalloy 我在这篇文章中加入了关于惰性评估的问题,因为这两个概念有些相关。通常在函数需要返回值之前不会评估函数的参数,所以我想知道这是否会影响我必须如何在我的实验语言中表示部分应用的函数。 -谢谢

标签: haskell concatenative-language


【解决方案1】:

swap [[>] dip] filter 不起作用,因为它假定每次调用您要过滤的报价单都可以访问n;这意味着filter 在运行时不能在堆栈上留下任何中间值,并且> 不会消耗n。您需要在该引用中捕获n 的值。

第一个“eta”——减少列表参数:

l n f = l [ n > ] filter
n f = [ n > ] filter

然后通过明确引用 n 并将其与 > 组合来捕获它:

n f = n quote [ > ] compose filter

(假设quote : a -> (-> a) a.k.a. unit,接受一个值并将其包装在引号中,compose : (A -> B) (B -> C) -> (A -> C) a.k.a. cat,连接两个引号。)

然后只需“eta”-reduce n:

f = quote [ > ] compose filter

我将“eta”放在引号中,因为它比 lambda 演算更通用,适用于堆栈上的任意数量的值,而不仅仅是一个。

您当然可以将部分应用程序分解为自己的定义,例如Cat 中的 papply 组合子,在 Joy 中已经定义为 swons (swap cons),但也可以这样定义:

DEFINE

  papply (* x [F] -- [x F] *)
    == [unit] dip concat ;

  f (* xs n -- xs[>=n] *)
    == [>] papply filter .

在 Kitten 中,这可以根据喜好以几种不同的方式编写:

// Point-free
function \> compose filter

// Local variable and postfix
-> n; { n (>) } filter

// Local variable and operator section
-> n; \(n <) filter

任何与函数式编程兼容的评估策略也与级联编程兼容——popr 是一种惰性级联语言。

【讨论】:

  • 非常感谢。您的article 是我对串联编程感兴趣的主要原因之一!
猜你喜欢
  • 1970-01-01
  • 2019-12-05
  • 2021-07-12
  • 2016-08-06
  • 2018-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多