Home
Objective Caml
ocaml@conference.jabber.ru
Пятница, 21 июня 2013< ^ >
f[x] установил(а) тему: OCaml / ОКэмл / Камль -- http://ocaml.org/ | Камло - http://camlunity.ru/ | Верблюды грязи не боятся! | release crap, enjoy NIH | репортьте баги официальным дилерам | ocaml мёртв и тормозит, move on | stdlib only? - ССЗБ | Fight FUD with fire | Мойте руки перед чатом | KEEP CAML AND CURRY ON | F#, Coq - де-факто онтопик
Конфигурация комнаты
Участники комнаты

GMT+4
[00:23:27] tilarids вошёл(а) в комнату
[00:28:48] Kakadu вышел(а) из комнаты
[01:25:45] tilarids вышел(а) из комнаты: Machine going to sleep
[04:02:07] UncleVasya вышел(а) из комнаты
[04:29:24] f[x] вошёл(а) в комнату
[04:35:44] <f[x]> что за стрелки?
[04:36:03] <f[x]> интересно
[04:36:27] <f[x]> я то обхожусь низкотехнологичным Option.map_default - но оно читается корявн
[04:36:30] <f[x]> коряво
[04:44:38] f[x] вышел(а) из комнаты
[04:55:21] zinid вошёл(а) в комнату
[05:21:12] f[x] вошёл(а) в комнату
[06:40:59] f[x] вышел(а) из комнаты
[06:45:22] f[x] вошёл(а) в комнату
[07:42:07] Typhon вошёл(а) в комнату
[08:12:59] <f[x]> let zero = one
[08:13:07] <f[x]> вот уж не ожидал у себя такое увидеть
[08:35:43] tilarids вошёл(а) в комнату
[09:45:09] f[x] вышел(а) из комнаты
[10:38:01] f[x] вошёл(а) в комнату
[10:43:45] ermine вошёл(а) в комнату
[11:17:35] <ADEpt> gds: мне интересно про options и стрелки
[11:18:19] <ADEpt> как реализовать "в лоб" - понятно, но будет ли это выглядить "естесвеннее", чем >>= fun val -> ... ?
[11:36:21] tilarids вышел(а) из комнаты
[11:45:32] tilarids вошёл(а) в комнату
[12:07:32] <f[x]> пришла такая идея, тулза кодогенерации - которой на вход даёшь функцию и указание что какая-то часть возвращаемого значения не используется - а тулза уменьшает выражение так чтобы как можно меньше операций производить которые получают отбрасываемое значение
[12:07:46] <f[x]> вобщем удаление неиспользуемого кода отталкиваясь от неиспользуемых значений
[12:08:30] <f[x]> вариант решения с lazy не катит по той причине что lazy занимает место в возвращаемой структуре
[12:08:47] <f[x]> а если структура не просто тупл а что-то вложенное то там часто бывает неплохое упрощение
[12:09:04] <f[x]> сейчас такой "удалятор" пишется руками путём отсечения лишнего
[12:09:17] <f[x]> вопрос - мог ли такое бы камльп4 делать?
[12:10:12] <f[x]> пример let f s = let (a,b) = String.split s ":" in int_of_string a, float_of_string b
[12:10:28] <f[x]> и скажем float из результата не используется
[12:10:33] <f[x]> сокращение очевидно
[12:11:32] <f[x]> правило для удаления - удаляются все вызовы функций результат которых - подмножество неиспользуемых значений - ну и рекурсивно до фикса
[12:12:14] <f[x]> понятно что сайд-эффекты всё портят, но мне это нужно для всякого парсинга, а там сайдэффектов обычно нет
[12:12:26] <f[x]> отговорите меня кто-нибудь
[12:14:12] <f[x]> есть примеры таких тулзов в других языках?
[12:15:32] <f[x]> и наверное лучше кастрировать не на синтаксическом дерево, а где-нибудь повыше, к typedtree в 4.0 вроде дают доступ?
[12:15:39] <f[x]> * дереве
[12:28:33] <f[x]> вообще в идеальном мире это бы оптимизатор делал :(
[12:29:18] <f[x]> хотя я тут думаю что в случае когда результат парсинга представляется структурой можно делать так же - специализировать структуру
[12:55:08] Kakadu вошёл(а) в комнату
[13:19:49] tilarids вышел(а) из комнаты: Machine going to sleep
[14:06:39] tilarids вошёл(а) в комнату
[14:09:42] tilarids вышел(а) из комнаты: Machine going to sleep
[15:34:01] f[x] вышел(а) из комнаты
[15:38:21] tilarids вошёл(а) в комнату
[16:45:39] <gds> итак, стрелки клейсли определены то ли для монады, то ли для функтора (не помню, но для наших целей не важно).  Обозначим его параметризованным типом m 'a.  Например, option 'a для наших применений.  Стрелка клейсли -- выражение с типом 'a -> m 'b.  Композиция на них определена так:
value ( >=> ) : ('a -> m 'b) -> ('b -> m 'c) -> ('a -> m 'c) = fun a_mb b_mc -> fun a -> (a_mb a) >>= b_mc;
Обратите внимание, композиции совершаются не над m 'a, а над функциями.  Из-за этого оказывается, что строгость окамла не вредит -- каждый кусок это функция, а её тело будет вычислено только при подаче аргумента.
Например, если в lwt-манатке мне часто приходится добавлять fun () -> для того, чтобы сэмулировать io-манатку ( = работать с действиями вместо работы с тредами, каждый из которых может вполне вычислиться в постоянное значение, таким образом, выполняя сайд-эффект только однократно и не в нужное время).
Вот, можно составить композицию нужных стрелок клейсли, и вычислить её применением к ней аргумента.
# value q = (fun a -> Some a) >=> (fun b -> if b then Some 123 else None) >=> (fun c -> let () = Printf.printf "c=%i\n%!" c in Some ());
value q : bool -> m unit = <fun>
# q True;
c=123
- : m unit = Some ()
# q False;
- : m unit = None
Но >=> -- не совсем то, что надо для нашей задачи.  Сделаем что-то наподобие mplus, только для стрелок клейсли:
value ( <+> ) : ('a -> m 'b) -> ('a -> m 'b) -> ('a -> m 'b) = fun x y -> fun a -> match x a with [ None -> y a | (Some _) as xres -> xres ];
Ещё плюс -- в том, что <+>, как и >=>, работает со стрелками клейсли, то есть, их можно композиционировать.
Дальше можно написать
value finder = (khashfind myhash) <+> (klistfind mylist) <+> (fun a -> Some ("default value for " ^ a));
и оно будет работать.  При этом <+> оказалось левоассоциативным, то есть, поиск будет идти слева-направо.  При этом оно не будет вычислять выражения, которые вычислять не нужно, что отличает этот подход от подхода
Полный код -- на http://paste.in.ua/8386/
[16:45:53] <gds> > let zero = one
а что, вполне нормально, если работаешь с группами/моноидами, и изначально сформулировал их на нуле и сложении, а теперь используешь их для умножения.  Соответственно, let add = mult должно быть.
[16:47:39] <gds> ADEpt: кое-где будет естественно, кое-где нет.  Но я думаю о том, чтобы там, где использую lwt как io-манатку, функции верхнего уровня ограничить типом kl 'a 'b для нужных 'a и 'b.
[16:48:24] <gds> f[x]: про удалятор -- если код чистый, то coq сработает.
[16:49:59] <ADEpt> gds: ха. Надо попробовать переписать таким образом пару option-heavy модулей
[16:50:55] <gds> f[x]: а оптимизатор -- хрен его знает, поможет ли.  Вот, будут у тебя разные значения типа let ffst x = fst (f x) let fsnd x = snd (f x) let fmyproj x = myproj (f x) -- и будут ещё дополнительные 3 тела функции со специализацией относительно f и fst, snd, myproj?  Не захотят в инриа генерить столько кода.
[16:52:00] <gds> ADEpt: если код публичный, то будет очень интересно посмотреть до и после.
Кстати, эти же штуки не только над option работают -- list тут следующий кандидат.
[16:52:47] <gds> (тьфуты, не дописал то большое сообщение.  дописываю:
"отличает этот подход от подхода с вычислением всех option 'a значений и поиском первого из <>None"
)
[16:55:44] <ADEpt> а со списками какая семантика?
<+> = fun x y -> fun a -> List.concat_map (x a) ~f:(fun b -> y b) ?
[16:55:50] <ADEpt> gds: ^
[17:00:16] <gds> ADEpt: а вот не знаю, так как подобной операции не видел, и законов для неё соответственно, и проверить на соответствие законов не могу.
Про сигнатуру concat_map не знаю, это видимо core.  Но, если тупо, то, наверное, должно быть так: fun x y -> fun a -> List.append (x a) (y a).  То есть, тупое сложение результатов.  Ведь <+> : ('a -> m 'b) -> ('a -> m 'b) -> ('a -> m 'b).
А concat_map вполне записывается с >>= и >=>, будь он нужен.
[17:00:58] <ADEpt> да, согласен
[17:01:09] <ADEpt> (и да, это core. Грешен :)
[17:01:35] <gds> вы там на работе, наверное, предполагаете, что core у всех стоит, и аж вместо stdlib :)
[17:02:13] <ADEpt> gds: да не то чтобы предполагаем ... Просто привыкаешь к функциям-сигнатурам, и потом пишешь это везде не задумываясь
[17:02:34] <gds> это согласен.
[17:52:58] Typhon вышел(а) из комнаты: Replaced by new connection
[17:53:08] Typhon вошёл(а) в комнату
[20:01:32] f[x] вошёл(а) в комнату
[20:19:09] komar вышел(а) из комнаты: Replaced by new connection
[20:19:09] komar вошёл(а) в комнату
[20:30:22] <f[x]> gds: явно не захотят, и вообщем-то правильно, не везде же нужно, только в критичных местах
[20:30:32] <f[x]> я то знаю где у меня критичные места, а компилер - нет
[20:33:56] Kakadu вышел(а) из комнаты: Logged out
[21:18:47] Typhon вышел(а) из комнаты
[21:32:15] tilarids вышел(а) из комнаты: Machine going to sleep
[21:59:06] f[x] вышел(а) из комнаты
[22:11:09] ftrvxmtrx вышел(а) из комнаты
[22:37:50] tilarids вошёл(а) в комнату
[22:41:34] zinid вышел(а) из комнаты
[22:52:02] Kakadu вошёл(а) в комнату
[23:27:37] ermine вышел(а) из комнаты
Powered by ejabberd Powered by Erlang Valid XHTML 1.0 Transitional Valid CSS!