Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38

Композиция и применение

17.12.2014, 13:07. Показов 1696. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пытаюсь как следует разобраться в обозначенных понятиях. По тексту книги вроде как всё понятно, но когда свой вариант "понимания" пытаюсь облачить в код, порой натыкаюсь на проблемы. Значит либо не до конца понимаю, либо что-то понимаю неверно.

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

Haskell
1
2
3
-- Works fine
func::Integer
func = sum (takeWhile (<10000) (filter odd (map (^2) [1..])))
Далее модифицирую (оптимизирую) код так, чтобы возвращаемый результат при этом оставался прежним.

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

Haskell
1
2
3
-- Works fine
func2::Integer
func2 = sum . takeWhile (<10000) . filter odd $ map (^2) [1..]
Аппликатор функции, т.е. ($) является оператором (т.е. инфиксной функцией, имя которой состоит только из спец. символов), применение которого правоассоциативно (в отличие от обычных функций, которые являются левоассоциативными). То, что стоит слева от $ вычисляется и передаётся в качестве параметра тому, что стоит справа от $. Т.е. получается, что $ я могу поставить, к примеру, не перед map, а перед исходным списком. Перед map же вместо $ нужно будет поставить точку:

Haskell
1
2
3
-- Works fine
func3::Integer
func3 = sum . takeWhile (<10000) . filter odd . map (^2) $ [1..]
Но тут у меня возникает вопрос: а что если в данном выражении вовсе убрать $? Тогда у меня должна получиться композиция из четырёх функций, на вход которой передаётся два аргумента. Композиция, как и аппликатор функций, является правосторонней, соответственно я ожидаю, что эти два аргумента будут переданы на вход функции map и далее всё должно проходить так же, как и для всех предыдущих вариантов. Т.е. мною предполагается, что будет работать такой код:

Haskell
1
2
3
--Don't working!
func4::Integer
func4 = sum . takeWhile (<10000) . filter odd . map (^2) [1..]
Как я понимаю, в данном коде композиция заканчивается на map и всё то, что находится правее - воспринимается как аргументы, порядок следования и типы которых должны соответствовать тем, которые ожидаются в map. Однако данный код не работает. Пытаюсь понять, почему, буду признателен за помощь.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.12.2014, 13:07
Ответы с готовыми решениями:

Композиция функций
Есть код: maxx :: Int-&gt; Int -&gt; Int maxx x y = case x&gt;y of True -&gt; x False -&gt; y max' :: Int-&gt; Int -&gt; Int -&gt; Int max' x...

Применение типов
Пытаюсь перейти от Prolog к Haskel. Надо сделать вычисление арифметического выражения. Пишу рекурсивную программу, аналогичную...

Выяснить, что представляют из себя отношения Ф композиция Ф и Ф композиция Ф^{-1}
Добрый день. До этого у меня было такое задание: Выяснить, какими из свойств: рефлексивность, антирефлексивность, симметричность,...

13
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
17.12.2014, 13:15
Навскидку, по памяти - будет воркс файн еще и так:
Haskell
1
2
func5 = ( sum . takeWhile (<10000) . filter odd . map (^2) ) [1..]
func6 = f [1..] where f = sum . takeWhile (<10000) . filter odd . map (^2)
0
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
17.12.2014, 13:25  [ТС]
Если Haskell в коде func4 не отделяет (^2) от map, то получается частично применённая функция, которая ожидает на входе один параметр (список). Т.е. и в случае такой интерпретации, я ожидал работу обозначенного выше кода.

Добавлено через 3 минуты
Цитата Сообщение от _Ivana Посмотреть сообщение
Навскидку, по памяти - будет воркс файн еще и так:
Меня интересует, где ошибка в моих рассуждениях, согласно которым я ожидал, что func4 должна работать.

Добавлено через 5 минут
Возможно композиции можно передавать только один параметр. Если так, тогда всё сразу проясняется.
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38177 / 21112 / 4307
Регистрация: 12.02.2012
Сообщений: 34,716
Записей в блоге: 14
17.12.2014, 13:42
Цитата Сообщение от include_brain Посмотреть сообщение
Возможно композиции можно передавать только один параметр.
- так любой каррированной функции можно передать только один параметр.
0
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
17.12.2014, 14:01  [ТС]
Цитата Сообщение от Catstail Посмотреть сообщение
- так любой каррированной функции можно передать только один параметр.
я в курсе о том, что в Haskell функции принимают не больше одного параметра. Однако в данном случае сигнатура последней в композиции функции ожидает два параметра. Я ожидал, что композиция будет "срисовывать" ожидание с последней функции (т.е. с map).

Добавлено через 13 минут
Т.е. композиции всегда следует передавать не более одного параметра, не зависимо от сигнатуры последней в композиции функции?
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
17.12.2014, 14:10
Цитата Сообщение от _Ivana Посмотреть сообщение
будет воркс файн еще и так
И так:
Haskell
1
func7 = sum $ takeWhile (<10000) $ filter odd $ map (^2) [1..]
0
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
17.12.2014, 14:14  [ТС]
Предлагаю не сворачивать от обозначенного в теме вопроса. Я не спрашивал обо всех возможных комбинациях переписания кода, а обозначил вопрос, который возник в процессе выполнения некоторых изменений.
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
17.12.2014, 14:15
Лучший ответ Сообщение было отмечено Mysterious Light как решение

Решение

Цитата Сообщение от include_brain Посмотреть сообщение
где ошибка в моих рассуждениях, согласно которым я ожидал, что func4 должна работать.
Ошибка в типизации. Оператор композиции принимает две функции и возвращает функцию, а ты передаешь ему значение. У него приоритет ниже, чем у применения функции, т.е. в func4 приоритеты такие:

Haskell
1
(sum) . (takeWhile (<10000)) . (filter odd) . (map (^2) [1..])
Выражение (map (^2) [1..]) имеет тип t, а должно -- t1 → t2.

А в func3 все в порядке с приоритетами, благодаря $:

Haskell
1
(sum) . (takeWhile (<10000)) . (filter odd) . (map (^2)) $ ([1..])
P.S. Не "don't working", а "don't works".
1
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
17.12.2014, 14:21
Если так хочется получить и вызвать (Integer => Integer) => [Integer] => Integer, можно так:
Haskell
1
func3 = ((sum .) . (takeWhile (<10000) .) . (filter odd .) . map) (^2) [1..]
Добавлено через 3 минуты
Цитата Сообщение от korvin_ Посмотреть сообщение
P.S. Не "don't working", а "don't works".
Не "don't works", а "doesn't work".
1
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
17.12.2014, 14:27

Не по теме:

Цитата Сообщение от Somebody Посмотреть сообщение
Не "don't works", а "doesn't work".
Вот я лоханулся. =)



Добавлено через 1 минуту
Цитата Сообщение от korvin_ Посмотреть сообщение
(sum) . (takeWhile (<10000)) . (filter odd) . (map (^2)) $ ([1..])
Если точнее, даже так:

Haskell
1
( (sum) . (takeWhile (<10000)) . (filter odd) . (map (^2)) ) $ ([1..])
0
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
17.12.2014, 14:47  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
Оператор композиции принимает две функции и возвращает функцию, а ты передаешь ему значение.
Всё, кажется дошло до меня. Спасибо. Я ожидал, что выражение
Haskell
1
sum . takeWhile (<10000) . filter odd . map (^2) [1..]
трактуется либо так:
Haskell
1
(sum . takeWhile (<10000) . filter odd . map (^2)) [1..]
либо так:
Haskell
1
(sum . takeWhile (<10000) . filter odd . map) (^2) [1..]
В первом случае map была частично применена, а во втором - нет.

Я и не подумал о том, что возможна такая трактовка:
Haskell
1
sum . takeWhile (<10000) . filter odd . (map (^2) [1..])
согласно которой вместо третьей функции передаётся вычисленное ею значение, в результате чего и происходит ошибка.

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

Добавлено через 1 минуту
Цитата Сообщение от korvin_ Посмотреть сообщение
P.S. Не "don't working", а "don't works"
Насколько я помню, при отрицании суффикс "s" не используется.

Добавлено через 54 секунды
Цитата Сообщение от Somebody Посмотреть сообщение
Не "don't works", а "doesn't work".
оно

Добавлено через 1 минуту
Цитата Сообщение от Somebody Посмотреть сообщение
Если так хочется получить и вызвать (Integer => Integer) => [Integer] => Integer, можно так:
Код Haskell
1
func3 = ((sum .) . (takeWhile (<10000) .) . (filter odd .) . map) (^2) [1..]
Я спотыкаюсь при чтении фрагментов ".) . " Не понимаю пока эту конструкцию.

Добавлено через 3 минуты
Цитата Сообщение от korvin_ Посмотреть сообщение
Если точнее, даже так:
Код Haskell
1
( (sum) . (takeWhile (<10000)) . (filter odd) . (map (^2)) ) $ ([1..])
Зачем? В чём смысл? Композиция совместно с аппликатором применяются в первую очередь для того, чтобы как раз таки избавиться от скобок, тем самым сделав код более читабельным.
1
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
17.12.2014, 15:44
Цитата Сообщение от include_brain Посмотреть сообщение
Зачем? В чём смысл? Композиция совместно с аппликатором применяются в первую очередь для того, чтобы как раз таки избавиться от скобок, тем самым сделав код более читабельным.
Естественно, я скобками показывал, как парсер воспринимает приоритеты.
0
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
17.12.2014, 15:51  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
как парсер воспринимает приоритеты
Откуда эта информация?
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
17.12.2014, 17:18
Цитата Сообщение от include_brain Посмотреть сообщение
Откуда эта информация?
Из надежных источников.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.12.2014, 17:18
Помогаю со студенческими работами здесь

Композиция
Допустим у меня есть класс точка, и отрезок, который строится с помощью двух точек. Так вот, я создаю два отрезка: P1 = new...

Композиция с++
Подскажите полузнайства! На примере как реализовать конструктор копии если у меня есть 2 класса с помощью композиции. class A{ ...

композиция
Всем привет. Помогите пожалуйста выполнить задание, т.к. я ещё в этом нуб) Даны три вещественные ф-ции. f(x)=-7x+8 g(x)=(x^7)+ 15...

Композиция
Добр время суток. Объясните пожалуйста принцип действия композиции и как с ней работать и что это такое. Искал инфу в нете но что то не...

Композиция
F = {(x,y) | x = мама y} D = {(x,y) | x = сын y} вот что нужно решить : Помогите пожалуйста, ибо не понимаю как это...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru