Оператор Haskell по сравнению с функциональным приоритетом

Я пытаюсь проверить что-то для меня об операторе и функциональном приоритете в Haskell. Например, следующий код

list = map foo $ xs

может быть переписан как

list = (map foo) $ (xs)

и в конечном счете будет

list = map foo xs

Мой вопрос раньше был, почему первая формулировка не будет переписана как

list = (map foo $) xs

так как функциональный приоритет всегда выше, чем приоритет оператора, но я думаю, что нашел ответ: операторам просто не позволяют быть аргументами функций (кроме, конечно, при окружении их круглыми скобками). Действительно ли это правильно? Если так, я нахожу это нечетным, что нет никакого упоминания об этом механике/правиле в RWH, или Изучите Вас Haskell или любое из других мест, которые я искал. Таким образом, если Вы знаете место, где правило указано, свяжитесь с ним.

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

($) (map foo) (xs)

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

39
задан Boris 26 June 2010 в 21:34
поделиться

4 ответа

Вы правы. Это правило является частью синтаксиса Haskell, определенного в Haskell Report . В частности, обратите внимание в Разделе 3, Выражения, что аргумент приложения функции ( fexp ) должен быть aexp . Aexp позволяет использовать операторы как часть разделов, а также в выражении в скобках, но не только операторы.

В map foo $ xs синтаксис Haskell означает, что он анализируется как два выражения, которые применяются к бинарному оператору $ . Как отмечает sepp2k, синтаксис (map foo $) является левым разделом и имеет другое значение.

Должен признаться, я никогда особо не задумывался об этом, и мне пришлось поискать это в Отчете, чтобы понять, почему операторы ведут себя так, как они.

27
ответ дан 27 November 2019 в 02:14
поделиться

Во-первых, приложение (пробел) является «оператором» с наивысшим приоритетом.

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

2 `f` x

и преобразовывать операторы в префикс с скобками:

(+) 2 3

Итак, ваш вопрос немного сбивает с толку.

Теперь для определенных функций и операторов будет объявлен приоритет, который вы можете найти в GHCi с помощью ": info":

Prelude> :info ($)
($) :: (a -> b) -> a -> b   -- Defined in GHC.Base

infixr 0 $

Prelude> :info (+)

class (Eq a, Show a) => Num a where
  (+) :: a -> a -> a

infixl 6 +

Отображение приоритета и ассоциативности.

37
ответ дан 27 November 2019 в 02:14
поделиться

Операторы могут быть переданы как аргументы функции, если вы заключите их в круглые скобки (например, map foo ($) xs , который действительно будет передан как (map foo ($)) xs ). Однако, если вы не заключите их в круглые скобки, вы правы, что они не могут быть переданы в качестве аргумента (или присвоены переменным).

Также обратите внимание, что синтаксис (someValue $) (где $ может быть любым оператором) на самом деле означает нечто иное: он эквивалентен \ x -> someValue $ x , т. е. он частично применяет оператор к своему левому операнду (что в случае $ , конечно, не работает). Аналогично ($ x) частично применяет оператор к правому операнду. Итак, map ($ x) [f, g, h] будет оценивать как [f x, g x, h x] .

10
ответ дан 27 November 2019 в 02:14
поделиться

Разница в том, что инфиксные операторы помещаются между своими аргументами, поэтому этот

list = map foo $ xs

можно переписать в форме префикса как

list = ($) (map foo) xs

, что, по определению оператора $, просто

list = (map foo) xs
12
ответ дан 27 November 2019 в 02:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: