Применение частичной функции в языках каскадного программирования

Скажем, у меня есть функция 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 - это ленивый конкатенационный язык.

Другие вопросы по тегам