Comments 10
Частичное применение и каррирование — не одно и то же.
Частичное применение — это когда есть функция f(x, y), фиксируем (применяем), например, y — получаем g(x).
Каррирование — это когда функия f(x,y) преобразуется к (g(x))(y).
Частичное применение — это когда есть функция f(x, y), фиксируем (применяем), например, y — получаем g(x).
Каррирование — это когда функия f(x,y) преобразуется к (g(x))(y).
В определении функции для обозначения любого типа именно «а» используется, или можно "[x]", например, записать для обозначения любого списка?
У вас infifr 7 написано — это опечатка или есть такое слово?
Не совсем понятен код для функций curry и uncurry (что они делают понятно).
Ведь по объявлению у каждой из них один аргумент, а в определении указано соответственно 3 и 2. Как так?
У вас infifr 7 написано — это опечатка или есть такое слово?
Не совсем понятен код для функций curry и uncurry (что они делают понятно).
Ведь по объявлению у каждой из них один аргумент, а в определении указано соответственно 3 и 2. Как так?
infifr — опечатка.
Переменная типа — любая строчная буква или даже слово из строчных букв. Принято использовать первые буквы алфавита a b c…
В Haskell аргумент всегда один, если функция не константа.
Посмотрите еще раз на объявление:
curry :: ((a, b) -> c) -> a -> b -> c
А если я напишу вот так (что одно и тоже):
curry :: ((a, b) -> c) -> (a -> b -> c)
Берем на вход такую функцию (a, b) -> c и получаем такую a -> b -> c
uncurry :: (a -> b -> c) -> ((a, b) -> c)
На входе функция a -> b -> c на выходе (a, b) -> c
Переменная типа — любая строчная буква или даже слово из строчных букв. Принято использовать первые буквы алфавита a b c…
В Haskell аргумент всегда один, если функция не константа.
Посмотрите еще раз на объявление:
curry :: ((a, b) -> c) -> a -> b -> c
А если я напишу вот так (что одно и тоже):
curry :: ((a, b) -> c) -> (a -> b -> c)
Берем на вход такую функцию (a, b) -> c и получаем такую a -> b -> c
uncurry :: (a -> b -> c) -> ((a, b) -> c)
На входе функция a -> b -> c на выходе (a, b) -> c
Про операторы можно дополнить следующее. Если имя функции состоит из спецсимволов, то по умолчанию она употребляется как оператор (то есть стоит между аргументами), если из букв-цифр, то как обычная функция (то есть все ее аргументы стоят справа от имени). Существует способ изменить поведение по умолчанию: взяв имя из спецсимволов в скобки, получаем обычную функцию, а заключив обычное имя в обратные кавычки, получаем инфиксную.
Причем, это работает не только в вызове функции, но и в определении. Например:
Отдельно стоит отметить синтаксис «частичное применение» оператора:
Причем, это работает не только в вызове функции, но и в определении. Например:
(%%) :: Int -> Int -> (Int, Int)
x %% y = (div x y, rem x y) -- это определение, а не вызов
mod :: Int -> Int -> Int -- NB: на самом деле библиотечное определение mod не такое; оно использует класс
x `mod` y = ...
Отдельно стоит отметить синтаксис «частичное применение» оператора:
(+ 2) -- то же самое, что \x -> x + 2
(2 `mod`) -- то же самое, что mod 2
Хоть определения каррирования выдернуты из Прелюдии как есть, лучше преобразовать их в одну форму:
или так
В принципе наличие скобок не важно, и обе записи валидны:
Слово «операторы» редко применяется в Хаскеле. «инфиксная фукнция» используется чаще.
Дело в том, что любую функцию можно записать и в префиксной, и в инфиксной записи
curry :: ((a, b) -> c) -> (a -> b -> c)
uncurry :: (a -> b -> c) -> ((a, b) -> c)
или так
curry :: ((a, b) -> c) -> a -> b -> c
uncurry :: (a -> b -> c) -> (a, b) -> c
В принципе наличие скобок не важно, и обе записи валидны:
a -> b -> c -> d -> f === a -> (b -> (c -> (d -> f)))
Слово «операторы» редко применяется в Хаскеле. «инфиксная фукнция» используется чаще.
Дело в том, что любую функцию можно записать и в префиксной, и в инфиксной записи
add x y = x + y -- prefix 'add', infix '+'
add x y = (+) x y -- prefix 'add', prefix '+'
x `add` y = (+) x y -- infix 'add', prefix '+'
x `add` y = x + y -- infix 'add', infix '+'
add2 x = (+ 2)
add2 x = (2 +)
add2 x = (`add` 2)
add2 x = (2 `add`)
Эта ваша уже третья статья, а читать ее все также не интересно и неприятно.
Объясните хоть людям что такое операторы, раз у вас статья о введении в программирование.
Какую цель вы преследуете в серии этих статей?
Объясните хоть людям что такое операторы, раз у вас статья о введении в программирование.
Какую цель вы преследуете в серии этих статей?
Хм. Что такое оператор проходят в школе. Этот термин к программированию относится лишь косвенно. Я думал, что это понятие известно читателям хабра.
Кому неприятно читать статью? Вам?
Цель преследую только одну — поделиться тем, что мне интересно с другими. Все стати в плюсе. А процентное отношение плюсов к минусам растет. Отсюда напрашивается два вывода:
1. Статья кому-то полезна
2. Качество статей повышается
Кроме того, хабр саморегулирующееся сообщество и, если бы статьи были «не интересными и неприятными» я бы уже был лишен возможности тут писать, уж поверьте.
Кому неприятно читать статью? Вам?
Цель преследую только одну — поделиться тем, что мне интересно с другими. Все стати в плюсе. А процентное отношение плюсов к минусам растет. Отсюда напрашивается два вывода:
1. Статья кому-то полезна
2. Качество статей повышается
Кроме того, хабр саморегулирующееся сообщество и, если бы статьи были «не интересными и неприятными» я бы уже был лишен возможности тут писать, уж поверьте.
Операторы можно составлять как угодно, за исключением следующих комбинаций:
« :: =… — @ \ | < — -> ~ => »
Однако следующий код работает:
(=...)::Int->[Char]->[Char]
a =... b = show a ++ ' ' : b
Проверяю:
ghci> :l src
[1 of 1] Compiling Main ( src.hs, interpreted )
Ok, modules loaded: Main.
ghci> let a = 123
ghci> let b = «asdf»
ghci> a =… b
«123 asdf»
ghci> (=...) a b
«123 asdf»
ghci>
Sign up to leave a comment.
Конспекты лекций «Haskell как первый язык программирования». Часть2