← All posts tagged dev

anton0xf
Java math dev fp tl:dr: Монада — это враппер с возможностью оперировать над завёрнутым значением. Если вы пишете на Java то уже наверняка знаете, что это. Никакой магии или скрытых смыслов.

Со мной щас случилось неожиданное. Т.к. я на Хаскелях и Скалах так никогда и не писал ничего длиннее пятка строк, то меня, как и большинство остальных людей несколько смущало понятие "монада". Хотя и знал уже, что по сути это всего лишь умное название для некоего враппера. Но всегда оставалось ощущение, что там есть какой-то более сложный нюанс, т.к. про всякие джавовые Optional и пр. обычно говорят "это близко, но не совсем оно", и добавляют с придыханием, что там есть ещё "монадические законы" и начинают разговор про Теорию Категорий, с которой у меня тоже как-то всё не складывается.
А тут на конфе в который раз зашла об этом речь, и я решил прикола для заглянуть в вику. Долистал до определения и всё понял!

java.util.Optional — это натурально монада. Как стримы и любой другой враппер, если к нему прицепить метод flatMap() с поведением, как у соответствующих методов Optional или Stream.

Раскрою на примере того самого Optional. Как пишут в вики монада `M` над типом `T` (пишут `M T`) — это тройка, состоящая из
1. конструктора типа (`M T`), т.е. например `Optional<T>`
2. конвертера `unit: T -> M T`. Напомню, что в стандартной математической нотации `f: X -> Y` — это функция из `X` в `Y`. Для моего примера это будет создание Optional из значения, т.е. в той же нотации: `Optional::<T>of : T -> Optional<T>`
3. и комбинатора `(>>=): (M T, T → M U) → M U`, т.е. функа, который употребляет монаду и другой функ, который из значения, в неё завернутого, делает другое значение, завёрнутое в эту же монаду, и применяет второе к содержимому первой. Т.е. в точности то, что делает Optional::flatMap, если понимать объект, у которого этот метод вызывается, как неявный первый аргумент. Точнее если у нас есть `x : Optional<T>` (переменная `x` типа `Optional<T>`), то `x::<U>flatMap : (T -> Optional<U>) -> Optional<U>` (или как пишут в javadoc: `Optional<U> flatMap​(Function<? super T,​? extends Optional<? extends U>> mapper)`), что отличается от сигнатуры в определении только тем, что `x` — это неявный параметр, поэтому его тип e у меня написан отдельно, но это исключительно синтаксическая особенность — в том же Python этот аргумент пишется в сигнатуре методов явно.

Ну а "законы" — это абсолютно тривиальные ожидаемые от врапера свойства:
+ `unit(x) >>= f <-> f(x)` — означает что flatMap() применяет свой аргумент с завёрнутому значению, а не делает что-то более хитрое: `Optional.of(x).flatMap(f) == f(x)`
+ `ma >>= unit <-> ma` — если есть переменная `x : Optional<T>`, то примерение `flatMap()` к `Optional::of` ничего не поменяет: `x.flatMap(Optional::of) == x`
+ `ma >>= λx → (f(x) >>= g) <-> (ma >>= f) >>= g` — некое правило ассоциативности применения `flatMap()`, т.е. если `x : Optional<T>`, и `f: T -> Optional<U>`, а `g: U -> Optional<V>`, то `x.flatMap(x -> f(x).flatMap(g)) == x.flatMap(f).flatMap(g)`
anton0xf
dev Prolog LOL ml Решил тут немного про Пролог почитать.
Чувак пишет:
It is unlikely that shorter formalisms that are equally clear and expressive exist.

И приводит пример вычисления длины списка (см. скриншот)

Моя реакция: "А-ха-ха! Кто-то паттернматчинга не видел"
let rec length = function [] -> 0 | _::l -> 1 + length l
(пример на OCaml)

anton0xf
dev habr HR задачки programming Чувак на хабре жалуется, что ему дали на собеседовании трудную задачу и заставили её писать в блокноте, и он не смог в итоге её решить за полчаса.
Из его претензий я согласен только с тем, что невозможность запускать свой код в процессе — это отстой. А вот не знать, что такое поиск в ширину, это уже явный фейл. К тому же его окончательное решение, полученное, как я понял, через пару дней, какое-то излишне многословное.
Я вот решил эту задачку, не смотря на его "решения", за 15 минут. Из них 5 ушло на заполнение дерева и минимальную визуализацию, 8 на написание функции, решающей задачу, и 2 на запуск и исправление единственной ошибки (в процессе написания я решил переименовать одну из локальных переменных, и не везде поменял её название).

Не думаю, что я особенно умный, или что быстро решил задачу (меня от части оправдывает только то, что я js практически не умею). Но, судя по голосованию внизу статьи, большинство читателей согласны с тем, что это либо слишком сложная задача (и на практике такие задачи не встречаются), либо не проверяющая сообразительность кандидата. И вот это, имхо, уже бред.
anton0xf
dev ? Android programming Посоветуйте годный текстовый редактор с подсветкой синтаксиса (чем больше поддерживает языков — тем лучше, но сейчас нужен Octave/Matlab) под первотег
anton0xf
MySQL dev SQL ? есть запрос, который возвращает наборы (date, action, count), где date — это дата, action — строка, а count — число.
для каждой даты в наборе есть несколько записей с разными action'ами. каждая пара (date, action) встречается один раз. action'ов, например, 3 разных.
хочу из этого получить наборы (date, action1_count, action2_count, action3_count), где action$i_count — это count из исходного запроса, соответствующий значению action='action1'.
как это лучше сделать?
anton0xf
math dev work ? programming есть датчик, выдает вещественные значения. выдает он их часто и значения меняются (как правило) мало, но собирается их много. изредка происходят (услоно мгновенные) скачки, после которых все тоже довольно гладко (в пределах погрешности измерения и всяких шумов).
anton0xf
humor Java dev ant ivy читаю доку по Apache Ivy:
(обсуждается подход, при котором каждому интеграционному билду модуля назначается отдельная версия, т.е. текущие билды в процессе разработки не переписывают старые, а хранятся все)
On the other hand, the main drawback of this solution
is that it can produce a lot of intermediate versions,
and you will have to run some cleaning scripts in your
repository unless your company name
starts with a G and ends with oogle :-)

там, вообще, много веселых шуток.
anton0xf
dev testing WTF ? как-то так получилось, что в словах "unit testing" слово "unit" уже нифига не значит и так назвают любое автоматизированое тестирование. даже вещи навроде Silenium'а, по мнению некоторых особо-одаренных, позволяют писать юнит-тесты.
anton0xf
quote dev GUI cli Unix *linux *windows
Коммерческий мир, как правило, стремится к моде новичков, потому что (а) решения о покупках часто принимаются на основе тридцатисекундного пробного использования и (b) необходимость поддержки пользователей при этом сводится к минимуму, поскольку им предоставляется упрощенный до абсурда GUI-интерфейс. Я нахожу многие не-Unix-системы очень неудобными, поскольку, например, они не предоставляют способа выполнять какие-либо действия с сотней или тысячей файлов; я хочу написать сценарий, но он не поддерживается. Основная проблема таких систем заключается в предположении, что все пользователи постоянно остаются начинающими, и, следовательно, они отвергают Unix, поскольку она в данную модель не вписывается.
(c) Майкл Леск
anton0xf
quote dev GUI cli Unix *linux *windows
"Дружественные" GUI-интерфейсы других операционных систем имеют свои собственные проблемы. Поиски необходимых кнопок подобны игре в Adventure: интерфейсы в этих системах настолько же трудны, насколько любой интерфейс командной строки в Unix, за исключением того, что пользователь теоретически может "найти сокровища" после достаточного исследования. В Unix пользователю необходимо руководство.
(c) Брайан Керниган