• Говорят, Haskell — язык для гениев и академиков. Правда?



      Однажды я разговаривал с основателем израильского стартапа, который разрабатывал скоростную базу данных на GPU. В их стеке были Haskell и C++, и основатель жаловался, как тяжело найти людей в команду. В Москву он прилетал в том числе искать хороших программистов.

      Я осторожно спросил, не лучше ли было использовать что-то более распространенное и новое. И хоть ответ был вежливым и конструктивным, между строк мне показалось: «Пфф, даже не упоминай эти игрушечные япы».

      Все, что я слышал про Хаскель со стороны с тех пор, сводилось к одному — «с ним шутки плохи». Чтобы узнать хаскелистов получше, я пришел с расспросами к ним в телеграм-чат. Было довольно страшно, и как оказалось, не зря.

      О Хаскеле не стремятся говорить популярно, и на такие затеи, кажется, поглядывают с презрением. Уж если говорить — то с максимальной полнотой и объективностью. «Одно из характерных качеств Хаскеля как языка и сообщества в том, что они вместе не стремились стать популярными, дав простой ответ на популярные вопросы. Вместо этого выстраивали логичный principled путь решения реальных проблем, а не быстрого проникновения в сердце прохожего интересующегося» — написали мне там.

      Тем не менее, несколько человек рассказали о своем опыте, и я собрал их мнения здесь.
      Читать дальше →
    • Аппликативные парсеры на Haskell

      • Tutorial


      Мотивация


      Когда я только начинала осваивать Haskell, меня очень раздражало повсеместное использование сложных абстракций вместо каких-то конкретных решений. Мне казалось, что гораздо лучше всегда следовать принципу KISS и писать велосипеды с использованием элементарных конструкций языка, чем разбираться во всех этих классах типов, чтобы где-то в итоге написать одну якобы удобную конструкцию.


      Мне не хватало хорошего примера, где бы окупались усилия, потраченные на освоение "матчасти". Для меня одним из самых удачных таких примеров оказались парсеры. Теперь я довольно часто рассказываю про них, когда у меня спрашивают, для каких распространённых задач можно красиво использовать Haskell.


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


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

      Читать дальше →
    • О фракталах, мартингалах и случайных интегралах. Часть первая

      • Tutorial

      На мой взгляд, стохастические исчисления — это один из тех великолепных разделов высшей математики (наряду с топологией и комплексным анализом), где формулы встречаются с поэзией; это место, где они обретают красоту, место где начинается простор для художественного творчества. Многие из тех, что прочли статью Винеровский хаос или Еще один способ подбросить монетку, даже если и мало, что поняли, всё же смогли оценить великолепие этой теории. Сегодня мы с вами продолжим наше математическое путешествие, мы погрузимся в мир случайных процессов, нетривиального интегрирования, финансовой математики и даже немного коснемся функционального программирования. Предупреждаю, держите наготове свои извилины, так как разговор у нас предстоит серьезный.
      Читать дальше →
      • +34
      • 10,3k
      • 5
    • Учим поросёнка на моноидах верить в себя и летать

      • Tutorial

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



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

      Читать дальше →
    • Стековая машина на моноидах

      • Tutorial

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


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


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

      Читать дальше →
    • Данные высокого рода

        Да-да, вам не привиделось и вы не ослышались — именно высокого рода. Род (kind) — это термин теории типов, означающий по сути тип типа [данных].

        Но вначале немного лирики.

        На Хабре вышло несколько статей, где подробно описывался метод валидации данных в функциональных языках.

        Эта статься — мои пять копеек в этот хайп. Мы рассмотрим валидацию данных в Хаскеле.

        Валидация типом


        Ранее было рассмотрен пример методики валидации при помощи валидации типом:

        type EmailContactInfo  = String
        type PostalContactInfo = String
        
        data ContactInfo = EmailOnly EmailContactInfo | 
                           PostOnly PostalContactInfo | 
                           EmailAndPost (EmailContactInfo, PostalContactInfo)
        
        data Person = Person 
          { pName :: String,
          , pContactInfo :: ContactInfo,
          }

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

        Валидация данными высокого рода




        В этой статье мы посмотрим иной метод валидации — при помощи данных высокого рода.

        Пусть у нас есть тип данных:

        data Person = Person
          { pName :: String
          , pAge  :: Int
          }

        И мы будем валидировать данные лишь в том случае, когда валидны все поля записи.
        Поскольку Хаскель по функциональным возможностям на голову превосходит большинство функциональных языков, на нём можно легко избавится от большинства рутины.

        Тут можно и поэтому данный метод широко используется среди авторов библиотек на Хаскеле.
        Читать дальше →
        • +16
        • 3,1k
        • 7
      • Как сделать ещё больше некорректных состояний ещё более невыразимыми

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

          Читать дальше →
        • Великая сила newtypes

            НовыйТип (newtype) — это специализированное объявление типа данных. Такое, что содержит лишь один конструктор и поле.

            newtype Foo a = Bar a
            newtype Id = MkId Word
            


            Типичные вопросы новичка


            В чём же отличие от data типа данных?

            data Foo a = Bar a
            data Id = MkId Word
            

            Главная специфика newtype состоит в том, что он состоит из тех же частей, что и его единственное поле. Более точно — отличаясь от оригинала на уровне типа, но имеет такое же представление в памяти, да и вычисляется строго (не лениво).
            Если вкратце — newtype более эффективны благодаря своему представлению.

            Да это ничего не значит для меня… Буду использовать data
            Не, ну в конце-концов, всегда можно включить расширение -funpack-strict-fields :) для строгих(не ленивых) полей или указать прямо

            data Id = MkId !Word
            

            Всё же сила newtype не ограничивается лишь эффективностью вычислений. Они значительно сильнее!
            Читать дальше →
            • +13
            • 2,9k
            • 2
          • ТРИЗ, Haskell и функциональное мышление

              При слове ТРИЗ, часто вспоминают тезис "идеальная система — та, которой нет (а ее функция при этом выполняется)". Как хороший админ, который не появляется в офисе, а все при этом исправно работает.


              Функция и система — критически важные понятия в ТРИЗ, говорят даже о функциональном стиле мышления. Правда при этих словах лично у меня сразу возникает ассоциация с функциональными языками программирования.


              Попробуем посмотреть, насколько органично идеи функционального мышления ТРИЗ отображаются на Haskell, одном чистых функциональных языков общего назначения.


              Читать дальше →
            • Cofree Will Tear Us Apart

              Всем привет.


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

              Читать дальше →
              • +18
              • 2,9k
              • 2

            Самое читаемое