
kir
21.07.2017
05:48:01
Но внутре-то у ней неонка^W коллбэки!

Aleksey
21.07.2017
05:48:25
Нет
f . g - тут f, это callback чтоли?
"Колбэки, это убогая беззаконная реализация монады", а не "монады, это такие коллбэки"

Google

Vladimir
21.07.2017
05:51:32
ого

Leonid
21.07.2017
05:52:58
Именем закона, прекратите свои реализации и сдавайтесь!

Vladimir
21.07.2017
05:53:43
но законы монад едины

Aleksey
21.07.2017
05:53:44
"Вы нарушили закон identity и приговариваетесь к пожизненному программированию на PHP!"

kir
21.07.2017
05:53:46
Я имел ввиду, что второй-то параметр (>>=) - коллбэк. А монада суть паттерн для последовательности вычислений.
На COBOL

Aleksey
21.07.2017
05:54:05
Да никакой это не колбек!

kir
21.07.2017
05:54:30
... а "продолжение"

Aleksey
21.07.2017
05:54:35
Это континюэйшн

Vladimir
21.07.2017
05:54:54
я вообще нем понял тезиса про колбэк, откуда это вообще

Aleksey
21.07.2017
05:55:32
"коллбэки", это просто ещё одна плохая аналогия. Как "буррито" и "контейнеры"

Vladimir
21.07.2017
05:55:33
не могу понять интуицию, которая за этим стоит
ну ок

Google

Vladimir
21.07.2017
05:56:22
буррито лол

Aleksey
21.07.2017
05:56:39
Кажется, что кто-то просто наелся обработки асинхронности в JS и теперь любую передачу функции в параметре считает "коллбэком" :)

kana
21.07.2017
05:56:50
Ну типа запустили операцию getLine и сказали мол, что когда она выполнится, нужно выполнить функцию после бинда

Aleksey
21.07.2017
05:56:51

kana
21.07.2017
05:57:14
Как бы колбеки так неплохо накладываются разве что на io

Leonid
21.07.2017
05:57:15
Тру

Aleksey
21.07.2017
05:57:19

Vladimir
21.07.2017
05:57:28
монада это шаверма. если вы хоть раз ели шаверму на районе, то знаете что такое монада

Aleksey
21.07.2017
05:57:37
просто IO в хаскеле, это не "выполнение", это конструирование значения, которое "поймет" только main

kir
21.07.2017
05:57:56
Оттуда, что до монад было примерно так:
data IO a
= PutStrLn String (() -> IO a) (Error -> IO a)
| GetLine (String -> IO a) (Error -> IO a)
...
А монады явились способом организовать этот беспредел

kana
21.07.2017
05:58:33
Таки нет. За счет ленивости нихера там не выполняется сразу. Иначе нельзя было делать бы даже простой if внутри

Aleksey
21.07.2017
05:58:39
Это не беспредел :) Это преждевременная free monad :)

Leonid
21.07.2017
05:58:56
Какой мультиплеер пошёл, прям deathmatch в чате

kana
21.07.2017
05:59:05

Vladimir
21.07.2017
05:59:05
а на каком уровне работает магия IO? что если у меня кастомный prelude и никаких инстансов монады я не определял?

kana
21.07.2017
05:59:10
Это мне нравится

Aleksey
21.07.2017
05:59:20
IO, кстати, не требудет монад

kir
21.07.2017
05:59:43
Тогда у тебя нет и типа данных IO. И ввода-вывода, соответственно

Google

Leonid
21.07.2017
05:59:47
GHC.Prim

Vladimir
21.07.2017
05:59:56
нету магии
ну как нет, ты хочешь сказать IO целиком выражен средствами хаскелла?

Aleksey
21.07.2017
06:00:10
монада реализована для IO только для того, чтобы поиметь do и композицию

Vladimir
21.07.2017
06:00:34
я не понимаю, на каком уровне он определен

Aleksey
21.07.2017
06:01:09
IO находится за пределами хаскеля. Это конечный продукт, который производит хаскелева программа
Программа на хаскеле вообще ничего не делает с вводом-выводом
Она просто конструирует "программу на другом языке", которую выполнит интерпретатор встроенный в рантайм - вот он то и делает IO и вообще весь с эффектами и грязью

kana
21.07.2017
06:03:04
То есть единственное место, где можно делать эффекты - IO?

Aleksey
21.07.2017
06:03:32
Эффекты, "повлияющие на внешний мир" - да

Vladimir
21.07.2017
06:04:00
видимо, есть просто "эффекты" в широком смысле

Aleksey
21.07.2017
06:04:14
Эффекты, которые не выйдут за пределы программы - запросто. State тот же

kana
21.07.2017
06:05:13
Ну так разве у стейта есть эффект? Он же просто возвращает новый "объект", следовательно иммутабелен, следовательно откуда там эффекты?

Aleksey
21.07.2017
06:06:02
С точки зрения кода, который назодится в State, происходит явная "мутация состояния"
Суть State в разделении работы по поддержке сквозного состояния и кода, это состояние использующего
Абстракция, короче
Так то всегда можно пачку аргументов протаскивать через все вызовы и писать без State и Reader, но это будет "low level"
State же позволяет сказать "вот мы имеет настоящую мутацию, можем инкрементить счётчик в цикле, всё как у императивщиков" в выделенном участке кода, но при этом за пределами stayteful блока оставаться в рамках чистого языка, т.е. иметь композицию, ссылочную целостность, вот это всё

Евгений
21.07.2017
06:09:26
Всё-таки хаскель это не агда, чтобы смотреть на него как на траслятор

Google

Aleksey
21.07.2017
06:10:26
Можно запросто откатиться к IO в виде ADT ничего принципиально не изменится. Зааффектится только код с unsafePerformIO
Линейность есть и в Identity
От реального мира абстрагируемся потому, что там перестаёт работать referential transparency например, и ленивость пропадает. И чтобы можно было рассуждать об остальном коде, он отделён от IO насовсем - поэтому нельзя сделать runIO безопасно, только unsafe
То, что IO "в хаскеле" не "выполняется", это объективный факт, всё таки. Любые порождаемые значения внутри IO приведут к ожидаемому эффекту тогда и только тогда, когда их ВЕРНЁТ main - вернёт рантайму, который уже "выполнит". До тех пор, пока main не вернёт значение, значение - первокласное, его можно дублировать, класть в чистые типы, возвращать из чистых функций, не боясь, что где-то не там что-то в консоль напечатается или откроется несуществующий файл

Leonid
21.07.2017
06:20:16
Или портал в ад

Aleksey
21.07.2017
06:21:17
Или ракеты запустятся

Евгений
21.07.2017
06:55:01
То, что IO "в хаскеле" не "выполняется", это объективный факт, всё таки. Любые порождаемые значения внутри IO приведут к ожидаемому эффекту тогда и только тогда, когда их ВЕРНЁТ main - вернёт рантайму, который уже "выполнит". До тех пор, пока main не вернёт значение, значение - первокласное, его можно дублировать, класть в чистые типы, возвращать из чистых функций, не боясь, что где-то не там что-то в консоль напечатается или откроется несуществующий файл
Это ровным счётом ничего не значит, любая State монада так себя ведёт.
Просто, очевидно, что main оборачивается runState, и всё. Во многих ЯП входная точка чем-нибудь обёрнута, чай не ассемблер

Aleksey
21.07.2017
06:57:13
Я и не спорю. Я имел в виду, что вычисление в IO конструирует значение, которое потом - за пределами программы - выполнится. Как и в случае со State, где конструируется пайплайн, через который будет протащен state

Евгений
21.07.2017
06:57:17
Единственная причина существования IO состоит в том, что RealWorld существует только в линейной форме, а в хаскеле этот факт без тайпкласса никак не записать. И всё

Aleksey
21.07.2017
06:57:57
IO можно представить в виде Writer, который копит [IOAction]
хотя больше на State таки похоже
в [IOAction] не получится сделать ветвление в зависимости от состояния мира...
Только если дерево накапливать

Евгений
21.07.2017
07:00:12
В моё время IO был явно записан как "State RealWorld a" :) Как щас хз

Aleksey
21.07.2017
07:01:52
Да примерно также. Но ведь State, это как раз про конструирование длинной лямбды, через которую будет протащен в данном случае "реальный мир" :)
поэтому когда мы пишем foo = print 42 >> print 24 никакой печати не происходит на момент определения - просто конструируется значение

kana
21.07.2017
07:05:21
Значение типа
Print 42 (\() -> Print 24 (\() -> Done))
Или обернуто все во free?

Евгений
21.07.2017
07:06:27

Aleksey
21.07.2017
07:06:43
\world -> (let newWorld = with world (Print 42) in \world -> ...

Google

Евгений
21.07.2017
07:07:19
И правильно говорить на языке редукций, если мы хотим не аналогии строить, а "понимать сущность языка"

Aleksey
21.07.2017
07:07:29

Anatolii
21.07.2017
07:14:56
Не хватает @qnikst

kir
21.07.2017
08:24:55
Да, он с 10 числа не показывается


Index
21.07.2017
08:49:20
Аппликатив почти как монада, только тензор не compose, а day convolution.
мне нравится альтернативное определение Applicative через <++> :: f a -> f b -> f (a, b), без аппликаторов
если ты рассматриваешь f как какой-то эффект, то получается, что <++> просто выполняет оба эффекта и ничего не делает с самими значениями. Что-то вроде моноида. В некоторых случаях там вообще напрямую моноид проглядывает – ну например Const x a у тебя будет аппликативом, если x моноид, и тогда <++> или <*> эти иксы тупо сложит:
> :t (<*>) @(Const String)
(<*>) @(Const String)
:: Const String (a -> b) -> Const String a -> Const String b
> Const "foo" <*> Const "bar"
Const "foobar"
как понять списки через эффекты или контексты, я без понятия (у меня никогда не получалось нормально), поэтому я просто запомнил, что со списками обычно можно твердить про себя “декартово произведение, декартово произведение” и вроде обычно работает. Есть ещё много штуковин, которые через эффекты мне сложно понять, и там приходится тоже запоминать, что будет делать Applicative/Monad
^ поэтому такое его понимание самое близкое к формализации
А любой аппликативный функтор является также и монадой, потому что day convolution можно конвертировать в compose:
dayToCompose :: (Functor f, Functor g) => Day f g a -> Compose f g a
dayToCompose (Day fb gc k) = Compose (
fb <&> \b ->
gc <&> \c ->
k b c)


Vasiliy
21.07.2017
09:02:45
> любой аппликативный функтор является также и монадой
ну нет, например

Vyacheslav
21.07.2017
09:03:42
не например
а прям очень точно
но любая монада — это аппликативный функтор

kana
21.07.2017
09:06:22
day convolution это вообще что-то дикое

kir
21.07.2017
09:14:30
Wait, wat. Реализуй instance Monad ZipList, например
> любой аппликативный функтор является также и монадой
ну нет, например
не например
а прям очень точно

Index
21.07.2017
09:15:05
Местами поменяйте