Зигохистоморфный
да и вообще, fix может быть выражен через полную рекурсию
Alexander
"хорошем" = оптимизатор справился
Зигохистоморфный
это я про hylo
Alexander
если есть control structure, то логично по ней рекурсию делать
Alexander
а список это нормальный control structure
Alexander
если же структуры для рекурсии нету и мы не порождаем контрольную структуру на выходе, но анонимная рекурсия - разумный выбор
Alexander
если мы порождаем контрольную структуру, то unfold* для этой структуры может быть понятнее
Alexander
кстати foo = loop where loop = ... вместо fix мне не нравится, обычно его не документируют нормально + легче словить лик
Alexander
особенно если там строков больше
Алексей
А какой лик там можно словить?
Dmitry
я повторю свое утверждение, если вдруг я увижу код, который по моему внутренему чувству стиля становится лучше за счет его использования, я ничего против fix иметь не буду
Ну вот код. Надо пачками загружать данные в БД: bracket (R.open dbFile defOptions) R.close (\db -> do cont <- mmapFileByteString inputFn Nothing let batchOps = map (uncurry R.Put . second B.tail . B.span (/=',')) $ B.lines cont fix (\f i batches -> do let (before,after) = splitAt batchSize batches R.write db def before unless (null after) $ do print i f (i + batchSize) after ) 0 batchOps )
Dmitry
Заводить ради этого функцию как-то не очень...
Alexander
вот тут, кстати, согласен
Alexander
выше 2 примера об этом были
кана
вот тут типа unfold лучше будет?
кана
попробовал одну из функций переписать
Alexander
один из них правда через forver / loopWhile можно переписать
Alexander
@kana_sama я бы через unfold писал
Alexander
я просто не вижу что стало луше в примере выше
Alexander
врочем и что стало сильно хуже не вижу
Alexander
если функция большая то ты не знаешь что написано в where тебе нужно смотреть вниз/скроллить
Alexander
если функция большая это проблема функции
Alexander
при этом если функция используется только 1 раз, то это не помогает
Alexander
вон выше 7 строк
Alexander
скролл = 20 строк
Alexander
я про перевод взгляда не зря сказал
Alexander
т.е. тебе нужно отвлечься от flow фукнкции и смотреть в другое место
Alexander
когда же ты смотришь на where - обратная ситуация - неясно где и почему и сколько раз используется
Alexander
если описание flow функции занимает 7 строк то это тоже стремно
Alexander
в идеале описание flow сводится к композиции правильно подобранных фрагментов
Alexander
:/
Alexander
вот выше не так?
Alexander
нет, @dmalkr ; но тот выше тоже подойдёт
Alexander
а по коду крылова у меня претензий и не было
Alexander
достаточно чистый код в котором анонимная рекурсия оправдана
Alexander
хотя имхо лучше бы выглядел ленивый список батчей которые потом заливаются в бд^$ а там он и есть
Dmitry
Ну да, чуть компактнее было бы.
Alexander
там список, но не батчей
кана
переписал на unfoldr)
кана
catMaybes понадобился из-за того, что в unfoldr нельзя пропустить отдачу результата шага (то есть просто дальше анфолдить не добавляя ничего)
Alexander
кстати, мне кажется хелпер который лениво превращает список в список списков ограниченной длины достаточно удобная штука
Dmitry
Вообще?
Dmitry
Или в данной задаче?
Alexander
вообще
Dmitry
Есть же Data.List.Split, там этих нарезальщиков полно
Alexander
ну тогда можно было бы его использовать вместо рекурсивного обхода
Alexander
я по библиотекам плаваю поэтому был не в курсе
Alexander
да, в split все есть
Alexander
адмирал "никогда не работал в команде"
Dmitry
ну тогда можно было бы его использовать вместо рекурсивного обхода
Ну можно было бы. Тут, имхо, вкусовщина. Или подключать модуль, смотреть его спеки, или побыстрому набросать явную рекурсию. Мне это не для продакшена, для экспериментов, поэтому побыстрому набросал.
Alexander
streamTraverseKeys (Transaction txn) edb = do (cursorKey, cur) <- lift $ allocate mdb_cursor_openX mdb_cursor_close (keyKey, pkey) <- lift $ allocate calloc free (valKey, pval) <- lift $ allocate calloc free fix (\f cursOp -> do result <- liftIO $ mdb_cursor_get cursOp cur pkey pval when result $ do yieldKey pkey f MDB_NEXT_NODUP ) MDB_FIRST release valKey release keyKey release cursorKey where mdb_cursor_openX = mdb_cursor_open txn (getMdbDBI edb) yieldKey pkey = liftIO (peek >=> mdbValToByteString $ pkey) >>= Stream.yield кстати, вот это что у меня было с fix
Alexander
требования к чистоте кода в экспериментах примерно на нуле :)
Alexander
и fix мне нравится гораздо больше чем loopWhile и прочие монстры из monad-loops и т.п. которые придётся или использовать или переизобретать
Alexander
которые тоже самое делают
Alexander
окей, с fix вы меня переубедили
Alexander
да, что важно, этих кейсов _мало_
Alexander
т.е. грубо говоря в проекте на 20к+ строк из у меня 2
Alexander
причем первым случаем я могу согласиться, что он там не обязателен, в общем не я его написал, я потил 0 времени на понимание, то почему бы и нет
Alexander
у меня по жизни есть проблема с тем, что из того что я что то понимаю не следует что это понимают другие
Alexander
веб-разработка, много джунов
Alexander
поэтому осторожничаю
Alexander
это логично
Alexander
но вообще fix можно рассматривать как паттерн типа applicative
Alexander
f <$> a <*> b <*> c - как работают понимают не все, но поняв что делает могут пользоваться и видеть его
Alexander
или join $ atomicaly (более редкий), да и вообще join
Alexander
собственно, я не встречал ни одного человека, который бы сходу понял как работает Y-комбинатор, но fix сравнительно понятен
Alexander
с другой стороны, людей которые каждый факториал пишут как point-free fix я недолюбливаю
Alexander
с этим соглашусь
Зигохистоморфный
ну вообще чтобы понять Y надо сначала проредуцировать на бумажке (\x -> x x) (\x -> x x) что есть база для рекурсии в ЛИ
Alexander
я пробовал, не помогло
Зигохистоморфный
тогда у меня плохие новости)
Alexander
ну хаскель тоже не может сам тип вывести
Зигохистоморфный
ну хаскель тоже не может сам тип вывести
ну а при чем тут хаскелль? это же ЛИ
Зигохистоморфный
ну хаскель тоже не может сам тип вывести
могу еще посоветовать такую кату https://www.codewars.com/kata/5443dd2d7fc4478154000ac6
Alexander
так я понимаю как fix работает
Alexander
я не понимаю почему
Андрей
где-то примерно тут https://youtu.be/7BPQ-gpXKt4?t=49m13s были эти слова