Pull to refresh

Haskell Tutorial с другой стороны

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

Я отношу себя к категории ленивых фотолюбителей. У меня есть неплохая «беззеркальная зеркалка», иногда на меня нападает желание пощёлкать чего-нибудь вокруг себя. Однако я ленив, и ковыряться потом в полученном фотоархиве у меня ни времени, ни желания нет. Как правило фотографии просматриваются один-два раза сразу после съемки путём подключения фотоаппарата к телевизору через HDMI кабель. Затем фотографии отправляются в небытие каталог ~/Pictures/Photos/Unsorted и, как правило, остаются там навсегда. С различным спец. ПО я как-то не сдружился, посему этот бардак просуществовал почти два года. И вот, на волне изучения Haskell, я созрел для решения проблемы.
Читать дальше →
Total votes 46: ↑42 and ↓4 +38
Views 15K
Comments 27

Пример асинхронной монады

Haskell *
Предположим, две программы общаются друг с другом по сети, но не изволят дожидаться ответа, поэтому ответы приходят в произвольном порядке. Чтобы разобраться, что к чему, с сообщением посылается номер, а в ответе шлется номер исходного (на которое отвечаем) сообщения и номер ответа для последующей коммуникации.

Нашей целью является описать последовательность приёма и отправок сообщений при общении с некоторым собеседником, а также иметь возможность использовать ввод/вывод (например, обращение к базе) между приёмами и отправками сообщений.

Как бы в коде на вашем предпочитаемом языке выглядел, например, такой диалог, с учётом того, что в любой момент (между любыми из этих пунктов) могут прийти какие-то другие запросы, которые тоже надо обработать, но не впутать случайно в этот диалог:
1. Посылаем число
2. Приходит число в ответ
3. Посылаем число из п.2 в квадрате
4. В ответ опять число
5. Выводим на консоль сумму чисел п.2 и п.4

Вот как это будет выглядеть на Haskell (функция example, разумеется, неблокирующая):
example :: Int -> AIO ()<br>
example v = do<br>
    x <- request v<br>
    y <- request (* x)<br>
    io $ print (+ y)<br>

Сравните это с блокирующей похожей функцией, которая, к примеру, запрашивает ответ у пользователя:
example :: Int -> IO ()<br>
example v = do<br>
    x <- request v<br>
    y <- request (* x)<br>
    print (+ y)<br>

Расковырять монаду!
Total votes 42: ↑38 and ↓4 +34
Views 1.9K
Comments 8

Расширяем C# с помощью Roslyn. Безопасные вызовы

.NET *Kotlin *
У вас никогда не возникало ощущения, что в языке X, на котором вы в данный момент программируете чего-то не хватает? Какой-нибудь небольшой, но приятной плюшки, которая может и не сделала бы вашу жизнь абсолютно счастливой, но определенно добавила бы немало радостных моментов. И вот вы с черной завистью посматриваете на язык Y, в котором эта штуковина есть, грустно вздыхаете и тайком льете по ночам слезы бессилия в любимую подушку. Бывало?
Будем лечить
Total votes 35: ↑33 and ↓2 +31
Views 8.5K
Comments 7

Скринкаст: монада Maybe на языке C#

Programming *.NET *Algorithms *
Небольшая иллюстрация того, как на языке C# реализовать монаду Maybe и зачем это вообще нужно. Смотреть видео рекоммендуется в разрешении 720p.



Сопутствующую статью можно найти тут (англ. яз.). Комментарии приветствуются!
Total votes 54: ↑44 and ↓10 +34
Views 20K
Comments 41

И снова про монады в PHP

PHP *Programming *Functional Programming *
Sandbox


После прочтения вот этого материала томным и прохладным вечером пятницы у меня осталось некоторое чувство неудовлетворенности и жжения где то снизу. Я сидел со рвением безумца обновлял комментарии в надежде, что найдется человек который скажет отчего же это происходит и я пойму что я не одинок. Но… увы этого не произошло. После чего я посетил сие творение и почувствовал тоже чувство и понял, что что-то нужно менять.
Читать дальше →
Total votes 36: ↑27 and ↓9 +18
Views 14K
Comments 8

Слово на букву «М», или Монады уже здесь

ООО «ЦИТ» corporate blog Java *Scala *Functional Programming *


Про монаду ходит множество мемов и легенд. Говорят, что каждый уважающий себя программист в ходе своего функционального возмужания должен написать хотя бы один туториал про монаду — недаром на сайте языка Haskell даже ведётся специальный таймлайн для всех отважных попыток приручить этого таинственного зверя. Бывалые разработчики поговаривают также и о проклятии монад — мол, каждый, кто постигнет суть этого чудовища, начисто теряет способность кому-либо увиденное объяснить. Одни для этого вооружаются теорией категорий, другие надевают космические костюмы, но, видимо, единого способа подобраться к монадам не существует, иначе каждый программист не выдумывал бы свой собственный.

Действительно, сама концепция монады неинтуитивна, ведь лежит она на таких уровнях абстракции, до которых интуиция просто не достаёт без должной тренировки и теоретической подготовки. Но так ли это важно, и нет ли другого пути? Тем более, что эти таинственные монады уже окружают многих ничего не подозревающих программистов, даже тех, кто пишет на языках, никогда не считавшихся «функциональными». Действительно, если приглядеться, то можно обнаружить, что они уже здесь, в языке Java, под самым нашим носом, хотя в документации по стандартной библиотеке слово «монада» мы едва ли найдём.

Именно поэтому важно если не постичь глубинную суть этого паттерна, то хотя бы научиться распознавать примеры использования монады в уже существующих, окружающих нас API. Конкретный пример всегда даёт больше, чем тысяча абстракций или сравнений. Именно такому подходу и посвящена эта статья. В ней не будет теории категорий, да и вообще какой-либо теории. Не будет оторванных от кода сравнений с объектами реального мира. Я просто приведу несколько примеров того, как монады уже используются в знакомом нам API, и постараюсь дать читателям возможность уловить основные признаки этого паттерна. В основном в статье пойдёт речь о Java, и ближе к концу, чтобы вырваться из мира legacy-ограничений, мы немного коснёмся Scala.
Читать дальше →
Total votes 43: ↑39 and ↓4 +35
Views 39K
Comments 33

Классы типов в Scala (с небольшим обзором библиотеки cats)

Scala *Functional Programming *

При слове "полиморфизм" сразу вспоминается объектно-ориентированное программирование, в котором полиморфизм является одним из столпов (Полиморфизм для начинающих). (Причём, по-видимому, более важным, чем другие столпы.) Оказывается, что можно достичь сходного эффекта и другим путём, который в ряде случаев оказывается более предпочтительным. Например, с помощью классов типов можно приписать новые возможности уже существующим типам, у которых нельзя изменить предка, или, используя тип данных с несовместимыми классами, "решить" проблему множественного наследования.

Читать дальше →
Total votes 21: ↑21 and ↓0 +21
Views 17K
Comments 12

Функциональный подход к транзакциям на Scala или пишем свою полезную монаду

Scala *Functional Programming *
Tutorial

Если вы работаете с одной базой данных которая поддерживает транзакции вы даже не задумываетесь о консистентности — база все делает за вас. Если же у вас несколько баз, распределенная система или даже к примеру MongoDB до 4 версии — все не так радужно.


Рассмотрим пример — мы хотим сохранить файл в хранилище и добавить ссылку на него в два документа. Конечно же мы хотим атомарности — либо файл сохранен и добавлен в документы либо ни то ни другое (тут и далее используется cats-effects IO):


saveDataToFile(data) // (1)
  .flatMap { file =>
    addFileRef(documentId, file) // (2)
      .flatMap { result =>
        addFileRef(fileRegistry, file) // (3)
          .flatMap { result =>
            ??? // (4, 5, ...)
          }
          .handleErrorWith { error =>
            // revert (2)
            removeFileRef(documentId, file).attempt >> IO.raiseError(error)
          }
      }
      .handleErrorWith { error =>
        // revert (1)
        removeFile(file).attempt >> IO.raiseError(error)
      }
  }

Уже непросто? Легко представить как количество операций растет и образуется Pyramid of doom.


Но мы же программисты! Давайте обобщим проблему и напишем код, который позволит избежать ненужной сложности и возможных ошибок.

Читать дальше →
Total votes 17: ↑17 and ↓0 +17
Views 3.6K
Comments 1

Перевозим волка, козу и капусту через реку с эффектами на Haskell

Algorithms *Haskell *Functional Programming *
🔥 Technotext 2020
Однажды крестьянину понадобилось перевезти через реку волка, козу и капусту. У крестьянина есть лодка, в которой может поместиться, кроме самого крестьянина, только один объект — или волк, или коза, или капуста. Если крестьянин оставит без присмотра волка с козой, то волк съест козу; если крестьянин оставит без присмотра козу с капустой, коза съест капусту.


В этой статье мы попытаемся найти обобщенное решение для такого типа головоломок и для этого будем использовать алгебраические эффекты.
Читать дальше →
Total votes 35: ↑35 and ↓0 +35
Views 11K
Comments 4

Повесть о стрелке и запятой

Programming *Haskell *Mathematics *Functional Programming *
В этой статье мы:

  • Познакомимся с сопряженными функторами
  • Узнаем, как отвечать на вопрос «что такое каррирование»
  • Притворимся, что у нас есть состояние (если есть только функции)
  • И вдогонку поиграемся с примитивной оптикой (линзами)

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


Читать дальше →
Total votes 30: ↑29 and ↓1 +28
Views 7.8K
Comments 17

Пытаясь композировать некомпозируемое: монады

Programming *Haskell *Mathematics *Functional Programming *

Сколько раз вы слышали эту мантру "монады не композируются"? Я потратил достаточно много времени, чтобы попробовать опровергнуть это утверждение, пытаясь решить проблему в лоб. Но как и многие вещи в математике, порой, чтобы попробовать что-то понять, иногда стоит сменить масштаб.

Читать далее
Total votes 19: ↑19 and ↓0 +19
Views 4.8K
Comments 0

Грокаем монады

Functional Programming *F# *
Sandbox
Translation

Самый распространенный способ объяснить монаду - зайти через теорию категорий. Знать, что монада - это моноид в категории эндофункторов и увлекательно и полезно для общего развития, но слабо помогает в практическом смысле. Второй, равный по популярности прием - прибегнуть к помощи образов, и вот мы уже складываем значения в коробочки и достаем их оттуда (или, вообще кошмар, катимся по железной дороге). Не спорю, образы - хороший способ посмотреть на явление, но тут мы равно удалились и от теории категорий и от практики.

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

Читать далее
Total votes 28: ↑23 and ↓5 +18
Views 9.5K
Comments 22

Грокаем монады императивно

Functional Programming *F# *
Translation

В предыдущем посте мы переизобрели Монаду на рабочем примере. У нас получился базовый механизм в виде функции andThen для типа option, но мы еще не достигли нашей конечной цели. Мы надеялись, что получится написать код, так же как если бы нам не нужно было обрабатывать значения option. Мы хотели писать в более "императивном" стиле. В этой части мы увидим как достичь этого при помощи технологии computation expressions языка F#, а также углубим наше понимание Монад.

Читать далее
Total votes 8: ↑8 and ↓0 +8
Views 4.5K
Comments 8

Ошибки, RxJS & Angular

Website development *Angular *TypeScript *

Что привлекает в Ангуляре экспертов и удручает начинающих? Одно и тоже, RxJS.

   Почему же это так сложно для начинающих? Возможно потому, что есть очень большое количество операторов, которые нужно просто знать, и без поиска понимать в чем разница между concatMap, switchMap и mergeMap. Почему же это так нравится тем, кто это уже выучил? Возможно, потому что вы начинаете понимать все могуществао RxJS, когда одним оператором вы можете сделать то, что в императивном коде писали бы полдня на двух страницах. Ведь это так приятно, ощущать себя богом, когда код просто отскакивает от ваших пальцев, а вы радостно рассказываете коллегам как вы классно и главное просто решили задачу.

Читать далее
Total votes 3: ↑3 and ↓0 +3
Views 1.3K
Comments 26