Создание конкатенативного варианта Haskell: приоритет применения и состав

Я изучаю основы конкатенационных языков, первоначальная идея которых заключается в том, что конкатенация имен функций такая же, как и состав функций, а не приложение функций, как в Haskell.

Joy, Forth или Factor являются postfix, что означает стек, но есть также несколько префиксных конкатенативных языков, таких как Om.

Интересно, теоретически вариант Haskell может быть конкатенационным языком, просто меняя (или даже выравнивая) приоритет композиции (теперь 9) с приоритетом приложения функции (теперь 10).

Если значения в Haskell являются просто функциями с нулевым аргументом, почему приложение функции отличается от композиции функции?, не является ли приложение функции тем же, что и компоновка с функцией с нулевым аргументом?.

Можно ли простым способом создать интерпретатор или прекомпилятор, который преобразует конкатенационный синтаксис в синтаксис Haskell, определяя новые операторы композиции и приложения с другим приоритетом и предполагая, что простая конкатенация без скобок является композицией? Я думаю, что это просто вопрос синтаксиса, я не прав?, И это позволило бы избежать многих случаев, когда мы должны использовать круглые скобки или оператор $ в Haskell. Или это более фундаментальная проблема, а не только синтаксис и приоритет?

Подсказка: предположим, что каждая функция и оператор в Haskell является префиксом, мы можем забыть в этом упражнении о нотации инфикса и всех видах "синтаксического сахара".

2 ответа

Решение

Лучшим ответом на мой вопрос является статья, на которую ссылается @Daniel Wagner во втором комментарии "Concatenative, Row-polymorphic Programming in Haskell", написанная Сами Хангасламми в качестве ответа на еще одну хорошую статью @Jon Purdy "Почему Вопросы каскадного программирования ".

Он показывает "один из способов реализации конкатенативного DSL внутри Haskell", и я действительно хотел знать, возможно ли это и как.

Если значения в Haskell являются просто постоянными функциями, почему приложение функции отличается от композиции функции?, не является ли приложение функции тем же, что и сочинение с постоянной функцией?.

Значения в Haskell не являются "постоянными функциями". Они также не являются "нулевыми функциями". Единственные вещи в Haskell, которые являются функциями, это те, чей тип включает конструктор function-arrow ->,

Постоянная функция - это функция, которая при любом входном сигнале возвращает тот же результат.

alwaysOne x = 1

map alwaysOne [1..5] == [1, 1, 1, 1, 1]

Производная такой функции равна 0. const Функция удобно создает такие функции, игнорируя второй аргумент и всегда возвращая первый.

map (const 1) [1..5] == [1, 1, 1, 1, 1]

Концепция "нулевой функции" имеет смысл только в языке, в котором функции могут принимать несколько аргументов - в Haskell определения функций с несколькими аргументами являются синтаксическим сахаром для определений связанных функций с одним аргументом в процессе, известном как каррирование. Все эти определения эквивалентны.

foo x y = x + y

foo x = \y -> x + y

foo = \x -> \y -> x + y

(На практике по соображениям эффективности среда выполнения GHC работает с функциями с несколькими аргументами и создает объекты замыкания только для частично примененных функций.)

Я думаю, что это просто вопрос синтаксиса, я не прав?

Основная идея конкатенационных языков состоит в том, что программы обозначают функции, а объединение двух программ дает программу, которая обозначает композицию этих функций. Так что если f это функция, и g это функция, то f g это программа, которая обозначает то, что мы написали бы в Haskell как g . f, В терминах абстрактной алгебры существует гомоморфизм от синтаксического моноида к семантическому моноиду. Это проблема синтаксиса.

Тем не менее, существует также проблема семантики. Эти функции должны манипулировать состоянием программы, которое неявно передается между ними, а состояние реальной программы является сложным, поэтому на практике конкатенационные языки, как правило, используют кортеж, обозначающий стек значений, потому что это просто и эффективно реализовать в реальных условиях. аппаратное обеспечение. Теоретически, состоянием программы может быть что угодно, например, карта или набор.

Я думаю, что семантика Haskell является настоящим камнем преткновения здесь, и хотя вы можете встроить конкатенативный DSL в Haskell, вам нужен конкатенационный язык, чтобы сделать его пригодным для повседневного программирования.

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