Задать вопрос
  • Как уменьшить вес скомпилированого кода на Haskell?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Опция GHC -split-sections

    Но её надо включать на всю кодобазу и все зависимости, а то оно подрежет один пакет, а весь остальной мир так и прилипнет целиком.

    cabal-install, глобально в `~/.cabal/config`:
    split-sections: true

    stack, в каждом проекте, в `stack.yaml`:
    ghc-options:
      "$everything": -split-sections
    Ответ написан
    Комментировать
  • Можно ли использовать код на C в Haskell?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Нет, не преобразовывает уже давно.

    Возможность есть: https://hackage.haskell.org/package/inline-c
    Ответ написан
    Комментировать
  • Какой язык програмирования дает скомпилированый файл с самым маленьким размером?

    wiz
    @wiz
    Ортодоксальный хаскелит
    11 мб это если использовать статическую линковку и не использовать опцию сборки "split-sections". Без неё весь библиотечный код запихивается в исполняемый файл вне зависимости используется он или нет. "split-sections" позволяет порезать библиотеки на блоки гораздо меньшего размера и тащить только то, что нужно.

    Кроме того, в Haskell будет ещё обязательная часть, т.н. "рантайм", которая обеспечивает все важные для исполнения программ функции вроде доступа к IO и сборке мусора.
    Ответ написан
    Комментировать
  • Как элегантно и переносимо определить instance Storable?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Можно взять derive-storable и вывести через Generic.
    Ответ написан
    Комментировать
  • Как поменять порядок списка на Haskell?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Порядок всего списка это `Data.List.reverse`.

    Поменять первый с последним элементы (судя по комментарию в ответе) это совсем другая задача.
    Чтобы её решить надо разбить на более простые.

    Последний кейс в этом коде вовсе не делает "поменять первый и последний элемент". Но что там должно происходить?
    Явно не то же самое, что вся функция в целом. Вытащите его в отдельную функцию и распишите что же именно она должна делать.
    Ответ написан
    Комментировать
  • Как происходит считывание в Haskell?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Задача делится на три части, которые лучше не смешивать.

    1) получение ввода (в main или аналогичной процедуре с доступом к IO)
    2) обработка данных (чистыми функциями)
    3) вывод результата (в main или аналогичной процедуре с доступом к IO)

    1 и 3 решается использованием функций из System.IO (если не выходить за пределы базовой библиотеки).
    Я настоятельно рекомендую вычитать весь ввод из файла или консоли и только потом приступать к его разбору. Иначе от попыток решить несколько разных задач в один заход будет каша в голове.
    Ответ написан
    Комментировать
  • Haskell и статическая линковка модулей?

    wiz
    @wiz
    Ортодоксальный хаскелит
    В новых cabal и stack можно использовать флаг GHC --split-sections (или соответствующие поля в конфигах проектов).

    В умеренно старых GHC есть устаревший аналог - split-objs.
    Ответ написан
    Комментировать
  • Как мне забилдить проект в stack?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Наличие README не влияет на сборку.

    Такие ошибки бывают когда сборка была преврана через Ctrl+C или была одновременно запущена из нескольких мест (терминал + IDE например).

    Лечится stack clean, удалением .stack-work и запуском заново.
    Если совсем плохо, то удалить всё и выгрузить код проекта заново.

    Плюс на винде ещё бывают свои проблемы с линкером. Обычно лечится обновлением до самого свежего GHC.

    PS: Вопрос трёхлетней давности, с тех пор в stack добавили немного защиты от такого и оно случается пореже.
    Ответ написан
    Комментировать
  • Какие вы посоветуете книги по Хаскелю?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Необязательные переменные это не страшно, если они улучшают понимание.
    На производительности они никак не сказываются. Глубокого смысла всё раскатать в pointfree нет и париться об этом не стоит.

    Если нет цели именно олимпиадничать алгоритмы, то лучше начать решать свои личные задачи и периодически просить сделать ревью. Через некоторое время мелочи всплывут сами, а если не всплывут, то и фиг с ними.

    На особенности с производительностью обратит внимание профилировщик.
    На особенности архитектуры обратят внимание уставшие мозги и пальцы.
    В итоге "выучить хаскель" поможет только опыт решения задач.
    Ответ написан
    1 комментарий
  • Что свисает из монады (перевод смысла)?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Результатами функций под композицией являются значения завёрнутые в данные монады m.
    Ответ написан
  • Можно ли сохранить промежуточный образ в контейнер и использовать его для других проектов?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Во-первых stack имеет родной способ сборки через докер: https://docs.haskellstack.org/en/stable/docker_int...

    Если хочется собирать докер-образы с некоторыми пред-собранными зависимостями, можно взять образ используемый в stack, сбилдить там зависимости проекта и уже результат использовать для сборки в докере.

    Если нужно собирать приложение в докере, а потом деплоить только бинарь, то это уже multistage.
    Ну такой вот примерно рецепт усредненный, потому что вариаций масса:

    FROM fpco/stack-build:lts-16.20 as build
    
    WORKDIR /opt/source
    RUN stack --resolver=lts-16.20 --system-ghc install example-exe
    
    FROM fpco/stack-run
    WORKDIR /opt/dist
    COPY --from=build-env /home/user/.local/bin/example-exe .
    
    CMD ./example-exe
    Ответ написан
    Комментировать
  • Работа с осью на haskell?

    wiz
    @wiz
    Ортодоксальный хаскелит
    С какой осью?

    Если с windows, то есть пакет Win32 - низкоуровневый, но зато всё в одной куче.

    Если с линуксами, то можно читать файлы из /proc.

    Для захвата экрана можно взять что-нибудь кроссплатформенное вроде gtk. Но если хочется прям стримить экран, я бы уже не стал выпендриваться и поискал способ сесть поверх ffmpeg.
    Ответ написан
    Комментировать
  • Как бизнес-логика и модель данных описывается в функциональных языках?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Технически, можно конечно вообще не описывать. Дали JSON и крутись как хочешь - в базе жсон, в программе жсон, на клиенте жсон. Но часто это неудобно и хочется его сначала перегнать во что-то прям сильно более специфическое для предметной области. Из {"something": "special"} в Special :: Something. И ещё столько раз, сколько того потребует достижение удобной работы. Ноль, один или более - не думаю, что это важно.

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

    Можно сделать тип
    data Something = Special | Ordinary | Composite This That
    а потом при выгрузке использовать Generics, тайпклассы, TemplateHaskell или что-нибудь ещё чтобы получить код который будет из БД перекладывать в язык.

    С бизнес-логикой всё ещё проще - код это данные, а данные это код. Есть EDSL на уровне хостового языка и логику ты пишешь на хаскеле, компилить и держать рядом с проектом. А есть DSL не использующие рантайм и к ним нужно прикручивать свою интерпретацию и сериализацию и хранить где угодно.
    Ответ написан
    2 комментария
  • Зачем в классе Num функция signum?

    wiz
    @wiz
    Ортодоксальный хаскелит
    mlyamasov, это родственник abs из мира комплексных чисел:

    That is, abs z is a number with the magnitude of z, but oriented in the positive real direction, whereas signum z has the phase of z, but unit magnitude.

    https://www.haskell.org/onlinereport/complex.html

    Класс Num действительно многие считают переусложнённым чудищем, но теперь уж до следующего репорта он с нами.
    Ответ написан
    Комментировать
  • Как решить задачу о быках, коровах и телятах на Haskell?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Это жадный алгоритм. Сортировка + свёртка решат для любого количества любых цен.

    Есть ещё чуть более весёлый вариант когда количество доступных для покупки позиций ограничено.
    Ответ написан
    Комментировать
  • Существует ли простой и элегантный способ добавить информацию о позиции в синтаксическое дерево с взаимно-рекурсивными типами?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Для работы с AST функторные кодировки более предпочтительны как раз за счёт возможности единообразно всем подсовывать новые фичи (а затем разом их скидывать). Да и с готовыми схемами рекурсии приятней работать, чем открывать фабрику велосипедов.

    Набросал пример с добавлением аннотаций на эти выражения: https://repl.it/@ICRainbow/RoundHuskyExabyte
    Fix2 не нужен, но надо чётко понимать чем будет являться функтор и неподвижная точка в каких выражениях. Это не сложно, но нужна практика.
    Ответ написан
    1 комментарий
  • Какая есть удобная IDE для Haskell по Ubuntu?

    wiz
    @wiz
    Ортодоксальный хаскелит
    В 2020 это vs code + haskell.
    Ответ написан
    Комментировать
  • Как вывести самодельный график в Haskell?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Если сделать график в бок, то решение тривиальное - выводить построчно, с палочками вправо.
    Менее информативным оно не станет, а код сильно упростится.

    Если хочется горизонтальную гистограмму, то можно сначала расчитать решётку 12xH, а потом транспонировать (повернуть на бок). Дальше для каждой ячейки можно посмотреть "уровень заливки" и вывести соответствующую юникодную палочку.

    Есть частный случай таких графиков, когда палочки используются высотой в 1 строку, называется Sparkline.
    Ответ написан
    Комментировать
  • Как сделать красивый вывод в Haskell?

    wiz
    @wiz
    Ортодоксальный хаскелит
    Show не занимается выводом, а только преобразует одно значение в другое. Выводом занимаются putStrLn и товарищи. Они на вход требуют [Char] или String. Если у вас уже есть значение типа [Char], то `show` на него делать не надо.

    Если на руках есть список строк, то надо смотреть в чём собственно задача. Если строки надо выводить одну за другой, без переносов, то можно их склеить через `unwords`. Полученную строку можно сразу отгружать в `putStrLn`. Если надо вывести несколько строк одну за другой, то можно либо склеить их через `unlines` и вывести за один `putStrLn`, либо сделать вызвать putStrln на каждую строку из списка в отдельности.
    Ответ написан
    Комментировать
  • Как работает where p x =... на Haskell?

    wiz
    @wiz
    Ортодоксальный хаскелит
    "Выдавливанием" из списка занимается `filter`, применяя функцию `p` к каждому элементу на входе.
    Если она возвращает True (т.е. когда остаток от деления равен нулю), то элемент зачисляется в выходной список.

    `head` тут берёт первый элемент из уже отфильтрованного списка. Или крашится с сообщением вроде "head: empty list" и лучше бы её заменить на `case`.
    Ответ написан
    Комментировать