LINUX.ORG.RU

Как в Хаскеле сделать try..catch..finally?

 ,


0

1

Как написать вот это:

зайти-в-сарай()
try
  ткнуть-палкой-в-осиное-гнездо-в-сарае()
catch all
  вернуть "Ой"
end

и вот это:

зайти-в-сарай()
try
  ткнуть-палкой-в-осиное-гнездо-в-сарае()
finally
  уходя-из-сарая-погасить-свет()
end

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

★★★★★

Последнее исправление: den73 (всего исправлений: 5)

Я думаю, что без погружения в язык (чтение книг, практика) ты ничего не поймешь. Будет только каша в голове. Потому что haskell - очень необычный язык

dave ★★★★★
()
Ответ на: комментарий от dave

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

qnikst ★★★★★
()
Ответ на: комментарий от dave

Так, я хотел спросить, а сколько же этих монад, дабы оценить объём работы. Пока понял, что есть вот такой список http://eax.me/monads/ . Хотя пока неясно, один ли тип монады Maybe или нет. Ну ладно, в целом ясно, теперь нужно дальше детализировать и это могу сделать только я сам. Спасибо!

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

На будущее, ставь нормально теги. В данном случае не хватает тега haskell. Я эту тему случайно заметил только что, когда всё интересное уже обмусолили.

Crocodoom ★★★★★
()
Ответ на: комментарий от den73

О! А что их сосчитали? Ну, ни фига себе! А я только для себя их штук 8 написал, не считая других типов вычислений...

dave ★★★★★
()
Ответ на: комментарий от dave

В принципе да, и меня интересует два аспекта:

монады как инструмент, могущий быть полезным для практических задач. Например, cps + клонирование состояния вычисления + многоверсионные данные - это то, что нужно для дешёвой инкрементной раскраски в редакторе. В CL пока эту задачу мы решить не смогли, хотя особый интерпретатор для этого был сделан, он оказался тупо неэффективным. Было потрачено море сил и никакого результата в итоге.

Опять же call/cc позволяет добавить легковесные треды туда, где их нет. «перегруженный оператор ;», как где-то охарактеризовали монады, может служить для тотальной трассировки, которая тоже нужна на практике.

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

С другой стороны, есть приёмы программирования, связанные с монадами, не обязательно в Хаскеле. Уже в Java впилили «потоки», которые кто-то характеризует как «приблизительно монады». В Cltl2 описаны «series» - видимо, то же самое.

Соответственно, встаёт задача сравнительного анализа, чтобы понять, что ценно, а что нет, и стоит ли что-нибудь к себе утащить. Но это вторично.

Монады как средство контроля эффектов в ленивом языке меня на данный момент не интересуют.

den73 ★★★★★
() автор топика
Ответ на: комментарий от dave

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

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

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

qnikst ★★★★★
()
Ответ на: комментарий от den73

Например, cps + клонирование состояния вычисления + многоверсионные данные - это то, что нужно для дешёвой инкрементной раскраски в редакторе.

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

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

Кстати, ты не думай, что так делают только в haskell!

Вот, возьми тот же rust. Популярный крейт futures-rs реализует или те же продолжения в точности, или нечто очень похожее, но слегка завуалированное. А сейчас почти каждый второй растоман носится с zero cost future-rs abstractions как с писанной торбой :)

dave ★★★★★
()
Ответ на: комментарий от den73

Монады нужны для удобной работы с побочными эффектами, вот и всё.

Если у тебя есть два самых обычных числа, ты просто пишешь a + b, и радуешься жизни.

А теперь представь, что

  1. эти два числа зависят от какого-то конфига
  2. при операции над этими числами тебе надо дополнительно логировать все операции
  3. это не обычные числа, а псевдослучайные
  4. эти числа пришли из какой-то функции, которые могла упасть с ошибкой.
  5. эти числа были введены пользователем.

Так вот, хаскель позволяет тебе по-прежнему практически буквально писать a + b (не будем углубляться в синтаксис), а всю заботу об эффектах берёт на себя. Соответствующие монады:

  1. Reader
  2. Writer
  3. State ну или сразу Random
  4. Maybe или Either
  5. IO

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

P.S. Конкретно для a+b достаточно аппликативного функтора (это шире, чем монада, у него меньше свойств), но начинающему на это можно забить.

Crocodoom ★★★★★
()
Ответ на: комментарий от qnikst

Что-то у тебя тенденция не понимать вопроса :)

Я спрашивал всего лишь о том, является ли данная мной ссылка не второй версией. Ну собственно, могу сам посмотреть, не трать своё время. В любом случае, спасибо за инфу.

den73 ★★★★★
() автор топика
Ответ на: комментарий от Crocodoom

при операции над этими числами тебе надо дополнительно логировать все операции

Во-во, это одна из задач, к-рые я уже озвучил. Остальные из озвученных тобой тоже интересны.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Для начала стоит понимать, что клонирования состояния, неявная параллельность, возможность исключений, CPS это эффекты. Если ты хочешь использовать это в ленивом языке, то монады это естественный вариант как писать вычисления с ними, если у тебя не ленивый язык, то есть варианты (называется effects), их можно выразить через Effect Monad. поэтому контроль за эффектами это основное практическое применение этой концепции.

Монады как средство комбинирования вычислений так же эффективно и в других языках, смотри rust с его синхронными исключениями и either (эффект прерывания вычисления) или futures (CPS).

Про эффективности и анализ это уже тебе к структурам данных (у которых может быть интерфейс Monad), а не к монадам как таковым.

qnikst ★★★★★
()
Ответ на: комментарий от den73

Более того

Известно, что любую разумную систему типов с эффектами (ну или *-passing style) можно транслировать в эквивалентную монадическую систему типов, которая тривиальным образом выражается в виде instance соответсвующей монады, скажем, в Haskell

Crocodoom ★★★★★
()

А как совместить оба варианта?

anonymous
()
Ответ на: комментарий от den73

а меня интересует, как работать с таким кодом

использовать Qt

Это личный выбор избегающих

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

next_time ★★★★★
()
Ответ на: комментарий от den73

у него было совсем недостаточно опыта работы с языком, так что часть объяснений не самые хорошие, а часть неверны. Это слова Дениса, не мои. Вообще это одна из книг, написанных из подхода «пока напишу книгу - сам разберусь».

qnikst ★★★★★
()
Ответ на: комментарий от den73

Она вроде онлайн доступна была свободно. Ну и если ты в районе питера живёшь, то я готов тебе хоть бумажную подарить.

qnikst ★★★★★
()
Ответ на: комментарий от den73

Меня интересуют инструменты для работы с императивным кодом. Например, cps преобразование. Инструментирование для отладки. Частичное применение. И прочая. Видимо, монады Хаскеля - это один из вариантов такого инструмента. Вот я и выясняю, насколько они применимы (удобны) для моделирования и анализа «обычного» императивного кода. Не только с исключениями, но и с обработчиками сигналов. Т.е. мне нужно не бросить исключение, а рассуждать о коде, бросающем исключение.

1. В х-ле полно библиотек для работы с AST. Частичное выполнение, подстановки, вывод ограничений для переменных ты вполне можешь сделать сам с их использованием. У Гонзалеса есть обзор про состояние экосистемы х-ля, список там.

2. Монада в х-ле - это просто специфический термин, означающий тип высшего порядка, с которым ассоциированы функции map, pure, apply и bind, удовлетворяющие нескольким простым правилам. Так что это никакой не инструмент для анализа, а только удобная абстракция (для которой сделали синтаксический сахар, да).

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

anonymous
()
Ответ на: комментарий от den73

Просто потому что один раз ткнуть в гнездо невесело. Кстати, раз уж ты поднял в теме раговор о учебниках хаскеля, то рекомендую «Изучай хаскелл во имя добра». Вот уж действительно просто о сложном.

Aswed ★★★★★
()
Ответ на: комментарий от den73

А вот теперь такой вопрос: в Книжном Лабиринте написано, что книга 2017 года издания. Но физически на книжке написано 2014. Также там в каталоге есть старая версия, т.е. видимо была допечатка или переиздание. Количество страниц совпадает. Есть ли разница?

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

И желательно без теорката и эндофункторов. Я нашёл счастье (т.е. определение монады) в википедии. Вот в таком же стиле, без зауми, хочу понять и всё остальное.

Ну ты ведь учился на математике вроде? Ты конечно можешь объяснить что такое двойной интеграл Лебега по замкнутому контуру или что такое «задача Коши в ОДУ» без анализа и зауми, но только одна проблема с таким объяснением - пользоваться им не получится ни для чего кроме как попонтоваться перед восьмиклассницами (а сейчас, говорят, они на это не шибко ведуться).

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

правда, как верно заметил Брагилевский где-то по ссылке выше - не обязательно знать машину Тьюринга чтобы научиться программировать.

В целом мне кажется анонимус прав и то что

Монада в х-ле - это просто специфический термин, означающий тип высшего порядка, с которым ассоциированы функции map, pure, apply и bind, удовлетворяющие нескольким простым правилам. Так что это никакой не инструмент для анализа, а только удобная абстракция (для которой сделали синтаксический сахар, да).

Таки подходящее описание (только не map, а fmap, и не помню про apply)

Но конечно не шибко полезное в смысле возможности использования на практике, так или иначе без хорошей вводной книжки и (главное!) хоть мало-мальской практики там ловить нечего. Список книжек у Брагилевского дали.

Оригинал learn you a haskell здесь http://learnyouahaskell.com/ , кажется, был так же перевод на русский, но я не читал его.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

Я уже купил книжку. Что там есть - то и буду осваивать. Вроде её хвалили как простую.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Посмотри, что такое монады семантически. Вот пишешь IOшный do, и внутри этого изолированного кусочка кода ты общаешься с внешним миром. Можешь это общение разбить на функции, часть из которых чистая (желательно большая), а часть ИОшная. То же самое с монадой стейт: внутри некоторого куска у тебя локально появляется стейт для цепочки трансформаций, куда можно писать и читать.

Так же и с монадой мейби: внутри куска кода появляется дополнительное действие (если пришел Nothing - ничего не делать с ним), которое производится на каждом последующем вызове, все кишки проверок спрятаны.

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

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

А типы... важно, но семантический аспект - «прятать и локализовать кишки» - для разработчика языка интереснее, имхо.

Тред читал только последнюю страницу, если чего упустил в своём спиче - ни на что не претендую.

Mihahail
()
Ответ на: комментарий от Mihahail

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

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

В принципе, вместо исключений в хаскеле используют монады (например Either). Они довольно успешно прячут кишки конкретно проверок. Плюс всякое конкаренси удобно с монадами. Вот тут с 35 минуты примерно (с планшета пишу) и ближе к концу демонстрируется «спрятывание кишок»: https://youtube.com/watch?v=E8I19uA-wGY

Без примеров кучерявого потока исполнения затрудняюсь прокомментировать, можно взглянуть на LINQ как пример их удачного применения. Для лиспоподобных же языков они потребуют адаптации: явно придётся допилить систему типов, написать всякие оптимизации... Если совсем расширить разум, то они (вкупе с аппликативными функторами и прочим) ведут себя как дээсели, чем-то напоминая таковые из Red.

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

Mihahail
()
Ответ на: комментарий от den73

языка с более кудрявым потоком исполнения, чем просто линия

В нормальном языке «кудрявый поток исполнения» — это «просто линия» с кейсами, чтобы легко было комбинировать, а эти твои try-catch-finally и прочее дерьмо — синтаксический сахар для бедных наркоманов. Поэтому эти кишки (try-catch-finally) кроме как макросами, которые мало где есть, хер спрячешь нормально без монад.

korvin_ ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.