Comments 23
Haskell автоматически выполняет каррирование всех функций, принимающих более одного параметра.Скорее, программист обычно выполняет каррирование всех функций, принимающих более одного параметра. Но можно и не выполнять. Так, функция, принимающая кортеж — это тоже, в некотором роде, функция нескольких параметров — при этом определение такой функции ничуть не сложнее определения каррированной функции.
add1 a b = a+b
add2 (a, b) = a+b
+3
Что интересно, для получения одного из другого можно использовать встроенные функции curry и uncurry, что довольно удобно для выполнения всяких операций над парами.
Например,
Надо понимать, что функции эти действуют для двух аргументов, больше — либо самому писать, либо удовлетворяться встроенными, которые, впрочем, есть и для 3х аргументов: hackage.haskell.org/package/utility-ht-0.0.5.1/docs/Data-Tuple-HT.html
Например,
map (uncurry (+)) xs
превращает список пар в список их сумм.Надо понимать, что функции эти действуют для двух аргументов, больше — либо самому писать, либо удовлетворяться встроенными, которые, впрочем, есть и для 3х аргументов: hackage.haskell.org/package/utility-ht-0.0.5.1/docs/Data-Tuple-HT.html
0
В Haskell функции без параметров называются константными функциями, поскольку каждая из них всегда возвращает одно и то же значение.
Это неправильно. В Haskell нет функций без параметров. В сигнатуре функции (после всех возможных подстановок) всегда присутствует хотя бы одна стрелка; если это не так — то это не функция, это конкретное значение.
+1
М. Липовача «Изучай Haskell во имя добра!», стр. 28:
Когда функция не принимает аргументов, говорят, что это константная функция.
-1
Формально это всё биндинги и разницы нет.
0
На самом деле, этот вопрос сложнее, чем Вам кажется. Элиот посвятил этому вопросу целый пост, который я рекомендую к прочтению.
Googolplex прав насчёт того, что в Haskell нет функций без параметров. И этот вопрос не связан с тем, есть ли у выражения биндинг или нет. Не все функции являются биндингами. Не все значения являются биндингами. Эта формулировка вообще некорректна. Некоторые выражения связаны с именами. Некоторые — нет. Но у каждого выражения есть тип. При этом некоторые выражения имеют тип функции, другие — нет.
Думаю, Миран Липовача осознанно опускает различие между функциями и биндингами (см. «Mixing up functions and definitions» у Элиота). Мне кажется, что на стр. 28 книги для начинающих это вполне допустимо. Пусть человек «пощупает» язык, а в терминологии он разберётся и потом.
Googolplex прав насчёт того, что в Haskell нет функций без параметров. И этот вопрос не связан с тем, есть ли у выражения биндинг или нет. Не все функции являются биндингами. Не все значения являются биндингами. Эта формулировка вообще некорректна. Некоторые выражения связаны с именами. Некоторые — нет. Но у каждого выражения есть тип. При этом некоторые выражения имеют тип функции, другие — нет.
Думаю, Миран Липовача осознанно опускает различие между функциями и биндингами (см. «Mixing up functions and definitions» у Элиота). Мне кажется, что на стр. 28 книги для начинающих это вполне допустимо. Пусть человек «пощупает» язык, а в терминологии он разберётся и потом.
0
Благодарю за ссылку, почитаю. Мои заметки по Haskell — это изложение того, как я понял ту или иную тему в ходе её изучения. Я не исключаю, что какой-то материал мною мог быть понят неверно. Опубликовывая информацию по Haskell через призму своего текущего понимания, я тем самым ожидаю, что более опытные люди смогут аргументированно указать мне на мои ошибки (собственно ради этого и опубликовываю).
+1
В книгах тоже иногда пишут фигню.
+1
Что такое «конкретное значение» в данном контексте?
0
Экземпляр конкретного типа данных (Int, String, Bool, etc).
0
Как отличить конкретный тип данных от абстрактного? неконкретного?
0
М. Липовача «Изучай Haskell во имя добра!», стр 159:
Примечание. Мы называем тип конкретным, если он вообще не принимает параметров (например Int или Bool) либо если параметры в типе заполнены (например, Maybe Char). Если у вас есть какое-то значение, у него всегда конкретный тип.
0
Тогда противопоставление «функции» «конкретному значению» некорректно.
Все параметры в типе ''Int -> Bool'' заполнены. Следовательно, он является конкретным.
Все параметры в типе ''Int -> Bool'' заполнены. Следовательно, он является конкретным.
0
Тогда функция, это просто (->) (с аргументами, разумеется, так как сама стрелка имеет kind * -> * -> *), а всё остальное — не функция.
Т.е. это не функция:
Зато это — функция:
Т.е. это не функция:
Maybe (a -> b) -- == Maybe ((->) a b)
Зато это — функция:
a -> Maybe b -- == (->) a (Maybe b)
0
Это значит — константа, элемент из множества нефункционального типа:
Определение нефункционального типа, я полагаю, можно ввести так.
Функциональный тип — это экспоненциал в категории Hask. Соответственно, нефункциональные типы составляют дополнение функциональных типов до всего класса объектов Hask, т. е. это все те объекты, которые не являются экспоненциалами.
pi :: Double
pi = 3.14 // вещественная константа
printHello :: IO ()
printHello = putStrLn "Hello" // константа - IO-действие
Определение нефункционального типа, я полагаю, можно ввести так.
Функциональный тип — это экспоненциал в категории Hask. Соответственно, нефункциональные типы составляют дополнение функциональных типов до всего класса объектов Hask, т. е. это все те объекты, которые не являются экспоненциалами.
0
Тема бесточечной нотации вообще не раскрыта. Лучше было бы сделать пример каким-то таким:
И потом объяснить, что под точкой подразумевается совсем не знак композиции.
countEven :: Integral a => [a] -> Int
countEven = length . filter even
И потом объяснить, что под точкой подразумевается совсем не знак композиции.
0
Надо бы в сигнатуру добавить еще одну переменную типа
func :: (Num a) => a -> a -> a -> a
func a b c d = a + b + c + d
-1
Only those users with full accounts are able to leave comments. Log in, please.
Немного о каррировании в Haskell