Vladislav
https://twitter.com/kmett/status/736182981145026561
Vladislav
но я не осилил
Vladislav
Я только общую постановку проблемы понял пока что.
Anonymous
То бишь, он утверждает, что есть в Hask вещи параметричные, но ненатуральные?
Vladislav
Такого не бывает
Anonymous
А, наоборрт
Vladislav
parametricity implies naturality
Vladislav
Он утверджает, что в Хаскеле неудобно теорию категорий моделировать, потому что там где в теоркатегорном языке говорят "for every" нельзя в Хаскельной версии просто воткнуть "forall".
Vladislav
И кидает ссылку, которая рассказывает о разнице формально.
Anonymous
Это уже совсем тонкие темы пошли. Надо читать.
Vladislav
Но суть в том, что если взять relevant квантификацию, т.е. pi из DependentHaskell вместо forall, то будет норм. Потому что pi не требует ни параметричности, ни натуральности
Vladislav
И натуральные трансформации можно будет выразить таким образом примерно: type f ~> g = pi a. f a -> g a Только он "больше", чем натуральные трансформации, т.к. не требует натуральности. Надо еще в комменте закон написать будет.
Anonymous
А чем вообще pi отличается от forall?
Vladislav
(Или не в комменте, если Agda)
Anonymous
Если Agda - то в глубоком юникоде.
Vladislav
по переменным, введенным через forall, паттерн-матчить нельзя. Вот если ты на Agda пишешь, то у тебя есть параметричность, если кайнд Set, и ее нет, если любой другой кайнд.
Vladislav
А в Dependent Haskell это квантификатором регулируется
Anonymous
А, то бишь, совсем deptypes
Anonymous
Паттерн-матчить в type-expr или в теле объявления?
Vladislav
т.е. такое невозможно id :: forall a. a -> a id x = case a of String -> "ha ha" _ -> x а с pi вместо forall возможно
Vladislav
в type-expr можно всегда через type families
Vladislav
речь про тело объявления
Anonymous
А в Агде, вроде, можно
Vladislav
в Агде можно, если введенная переменная не в Set
Vladislav
т.е. если ты натуральное число примешь, то можно, конечно
Vladislav
а если тип какой-то населенный, то нельзя
Vladislav
Но это странно, что от типа зависит параметричность
Vladislav
И McBride про это выступал и жаловался много, так что в DependentHaskell решили сделать "как надо".
Anonymous
А, то есть пример выше тоже не будет компилироваться?
Vladislav
Ага, такой хитрый id в Agda написать нельзя
Vladislav
потому что нельзя будет матчить по типу
Anonymous
Я понимаю, почему возможность так делать отобрали
Vladislav
Ее отобрали в т.ч. потому что Set особенный тем, что открытый
Vladislav
Ты можешь новые объявления делать и у него будут добавляться новые конструкторы
Vladislav
И подогнать под это нормальную теорию для паттерн-матчинга весьма нетривиально
Anonymous
Такие id обладают недоступной снаружи структурой и вообще. Как теоретики смотрят на то, что с pi у нас более чем бесконечное кол-во функций вида pi a . a -> a?
Anonymous
А Set1 тоже нельзя матчить?
Vladislav
Ну так рассмотри что-то вроде f :: pi (n :: Nat). forall (a :: Type). Vec n a -> Vec n a
Vladislav
Тебя же не смущает, что ты не параметричен по n :: Nat
Vladislav
И в зависимости от длины эта f может совершенно разные вещи делать
Vladislav
Например, для n как простых чисел делать reverse, а для остальных делать id
Vladislav
А Set1 тоже нельзя матчить?
Да, никакой Set lvl нельзя
Aleksei (astynax)
>>> False == False in [False] True
Это ещё пол-беды! Вот где "интересное": >>> (False == False) in [False] False >>> False == (False in [False]) False
Alexander
>>> False == False in [False] True
https://docs.python.org/3/reference/expressions.html#comparisons Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
Alexander
там получается (False == False) and (False in [False])
Aleksei (astynax)
>>> dis.dis(lambda: False == False in [False]) 1 0 LOAD_CONST 1 (False) 2 LOAD_CONST 1 (False) 4 DUP_TOP 6 ROT_THREE 8 COMPARE_OP 2 (==) 10 JUMP_IF_FALSE_OR_POP 18 12 LOAD_CONST 2 ((False,)) 14 COMPARE_OP 6 (in) 16 RETURN_VALUE >> 18 ROT_TWO 20 POP_TOP 22 RETURN_VALUE >>> dis.dis(lambda: (False == False) in [False]) 1 0 LOAD_CONST 1 (False) 2 LOAD_CONST 1 (False) 4 COMPARE_OP 2 (==) 6 LOAD_CONST 2 ((False,)) 8 COMPARE_OP 6 (in) 10 RETURN_VALUE >>> dis.dis(lambda: False == (False in [False])) 1 0 LOAD_CONST 1 (False) 2 LOAD_CONST 1 (False) 4 LOAD_CONST 2 ((False,)) 6 COMPARE_OP 6 (in) 8 COMPARE_OP 2 (==) 10 RETURN_VALUE
Aleksei (astynax)
False == False iff False in [False]
Aleksei (astynax)
Понятно, что сцепочили сравнение, непонятно, почему in, тоже "сравнение"
Alexander
а вот фиг знает, но я ради интереса сейчас спрошу в IRC'е Python'истов) интересно, что ответят
Aleksei (astynax)
Гвидо странный, поэтому такое
Aleksei (astynax)
В той же доке >>> nan = float('NaN') >>> nan is nan True >>> nan == nan False <-- the defined non-reflexive behavior of NaN >>> [nan] == [nan] True <-- list enforces reflexivity and tests identity first
Aleksei (astynax)
Так что всё плохо со здравым смыслом
Aleksei (astynax)
И даже понятно, почему так сделали - is быстрее, чем == - но в целом то адище получается!
Anonymous
Да что про Гвидо говорить, он в районе 2007 хотел выпилить map, filter и reduce и заменить их на циклы и свой ужасный list comprehension.
Anonymous
Из него же: "И я их добавил, только потому что они были нужны 1 лисп-хакеру, который прислал работающие патчи"
Anonymous
Насчёт map(f, y) возвращающего объект, из которого при чтении удаляются элементы не хейтили ещё?
Aleksei (astynax)
Гвидо - известный ФП-ниосилятор :)
Aleksei (astynax)
>>> i = map((1).__add__, [1,2,3]) >>> list(i) [2, 3, 4] >>> list(i) []
Aleksei (astynax)
"раньше такого не было"
Anonymous
У меня полчаса бомбило, когда я это выяснил.
кана
Интересно, что назначение монад я ещё более менее понимаю, а вот про аппликаторы не понимаю ничего. Нет, я знаю их интерфейс, я знаю, где они применяются, но совсем не понимаю концепции
Зигохистоморфный
Интересно, что назначение монад я ещё более менее понимаю, а вот про аппликаторы не понимаю ничего. Нет, я знаю их интерфейс, я знаю, где они применяются, но совсем не понимаю концепции
ну как бы когда ты юзаешь аппликативы то ты получаешь эффекты заложеные в структуру данных (а в монадках ты можешь управлять всем этим)
кана
Какие эффекты? Как оборачивание чистой функции в аппликатор и вызов этой функции с аргументом, который находиться внутри другого аппликатора, дает нам доступ к каким-то эффектам
Vasiliy
оборачивание чистой функции ничего не даст
Vasiliy
pure не добавляет никакой информации
кана
Я пока не очень понимаю, как работает IO. Пока что у меня это выглядит каким-то большим сум-типом со списком команд. И каждый раз, когда значение IO доходит до уровня выполнения, Хаскель выполняет команду, а потом вызывает колбеки
кана
И это как-то очень костыльно все
Anatolii
Мне кажется что до меня дошло после доклада Simon Marlow про haxl и зачем они applicative do запилили
Vasiliy
всё так, выполняет команду, вызывает колбэки
кана
на степике во 2 курсе по хаскелю хорошо про них рассказывается
Москвин? Смотрел его лекции в каком-то универе, до курсов не дошел
Vasiliy
мне стало более понятно, когда я про free почитал
кана
Объясни пожалуйста
Vasiliy
ну вот Identity, например... :D
кана
Возможно, сегодня будет тот самый день, когда мою голову пошатнет понимание
Зигохистоморфный
Возможно, сегодня будет тот самый день, когда мою голову пошатнет понимание
когда ты используешь аппликатив, то ты всегда уверен что сработает тот эффект который заложен в контейнерном типе (а в монадках ты управляешь этим) не всегда нужна монада, вот например для парсера аппликатив очень даже ок
Aleksei (astynax)
почему все всегда скатывается к "контейнеру типу"? нет никакого контейнера в общем случае