Применение частичной функции в языках каскадного программирования
Скажем, у меня есть функция haskell f n l = filter (n<) l
где требуется целое число n
и список l
и возвращает все целые числа в l
больше чем n
,
Я пытаюсь понять, как лучше написать эту функцию на таком языке, как Joy. У меня вообще была удача с преобразованием функции haskell в беспричинную форму f = filter . (<)
а затем пытается переписать это в радости оттуда. Но я не могу понять, как смоделировать частичное применение функции на конкатенативном языке.
До сих пор я пытался сделать что-то вроде swap [[>] dip] filter
, но, кажется, должен быть лучший / более чистый способ написать это.
Кроме того, я экспериментирую с написанием своего собственного конкатенативного языка и мне было интересно, может ли ленивая оценка быть совместимой с конкатенативными языками.
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)
ака unit
, принимает значение и упаковывает его в кавычки и compose : (A -> B) (B -> C) -> (A -> C)
ака cat
, объединяет две цитаты.)
Тогда просто "эта" -снижение n
:
f = quote [ > ] compose filter
Я поместил "eta" в кавычки, потому что он немного более общий, чем в лямбда-исчислении, и работает для любого количества значений в стеке, а не только для одного.
Конечно, вы можете выделить частичное приложение в его собственное определение, например papply
комбинатор в Cat, который уже определен как swons
(swap cons
) в Joy, но также можно определить так:
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
Любая стратегия оценки, совместимая с функциональным программированием, также совместима с конкатенативным программированием - popr - это ленивый конкатенационный язык.