说我有一个haskell函数f n l = filter (n<) l
,它接受一个整数n
并列出l
并返回l
中大于n
的所有整数
我正在尝试找出如何最好地用Joy之类的语言编写此功能的方法。总的来说,我很幸运能将haskell函数转换为无点格式f = filter . (<)
,然后尝试从那里用Joy重写它。但是我不知道如何用连接语言模拟部分函数应用程序。
到目前为止,我已经尝试做类似swap [[>] dip] filter
的事情,但是似乎必须有一种更好/更干净的方式来编写此代码。
此外,我正在尝试编写自己的连接语言,并且想知道惰性求值是否可以与连接语言兼容。
答案 0 :(得分: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)
(假设unit
又称compose : (A -> B) (B -> C) -> (A -> C)
,取一个值并将其包装在引号中,而cat
又称n
,将两个引号串联起来。)
然后只是“ eta”-减少f = quote [ > ] compose filter
:
papply
我将“ eta”放在吓人的引号中,因为它比lambda演算中的通用性更高,它可以处理堆栈中任意数量的值,而不仅仅是一个值。
您当然可以将部分应用程序分解为自己的定义,例如Cat中的swons
组合器,在Joy中已定义为swap cons
(DEFINE
papply (* x [F] -- [x F] *)
== [unit] dip concat ;
f (* xs n -- xs[>=n] *)
== [>] papply filter .
),但也可以这样定义:
// Point-free
function \> compose filter
// Local variable and postfix
-> n; { n (>) } filter
// Local variable and operator section
-> n; \(n <) filter
在小猫中,可以根据喜好以几种不同的方式来写:
out
任何与函数式编程兼容的评估策略也与串联式编程兼容-popr是一种惰性的串联式语言。