2

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

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

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

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

4

1 回答 1

3

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)aka unit, 接受一个值并将其包装在引号中,而compose : (A -> B) (B -> C) -> (A -> C)aka cat, 连接两个引号。)

然后只需“eta”-reduce n

f = quote [ > ] compose filter

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

你当然可以将部分应用分解到它自己的定义中,例如papplyCat 中的组合子,它在 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

任何与函数式编程兼容的评估策略也与级联编程兼容——<a href="https://github.com/HackerFoo/poprc" rel="nofollow noreferrer">popr 是一种惰性级联语言。

于 2019-05-02T22:36:56.170 回答