Alexander
в любом месте fix читается лучше чем let explicitRecursion = ... in explicitRecursion
Alexander
так же у fix гарантированно нету проблем с инлайнером
Alexander
в отличии от вложенной рекурсии
Alexander
никто же не предлагает через let это определять
Alexander
если нужна рекурсивная функция с настройкой аргументов то where гораздо приятнее смотрится
Alexander
нет
Alexander
точнее не всегда
Alexander
а можно на примере?
Dmitry
Пример:
withSomeResource (\resource -> do
let var1 =
let var2 =
someRecursion resource var1 var2
Dmitry
Как тут where всунуть?
Dmitry
Проще fix
Alexander
fix (\f -> recv >>= \case
-- for some reason creating a sheet returns a 'SetOpenedWorkbook' rather
-- than 'SetOpenedSheet'
WsAPI.SetOpenedWorkbook ow ->
case API.openedSheet ow <|> fmap API._sheetId (listToMaybe (API.openedWorkbookSheets ow)) of
Nothing -> throwM $ userError "No sheet in workbook!"
Just x -> pure x
_ -> f)
хотя бы так
Alexander
ещё если нужны повторы и выходы при работе с MVar
Alexander
тут кусок кода я бысто не найду, т.к. у меня его не должно быть
Alexander
в общем не то, чтобы fix часто нужно было, но многие циклы не заслуживают имени
Alexander
а для анонимных циклов - вполне нормально, особенно если они вложенные
Зигохистоморфный
ну также можно сделать и fixM
Alexander
кто то там писал про то что вложенные циклы это зло
Alexander
кроме тривиальных случаев
Alexander
вложенные циклы это надо
Зигохистоморфный
кстати всякие монадические анаморфизмы тоже ок)
rangeM :: Int -> IO [Int]
rangeM = anaM coalg where
coalg x
| x == 0 = return Nil
| otherwise = print ("Number => " <> show x) >> return (Cons x (pred x))
Alexander
Рома писал, т.к. писал их явно и получал лики, которым удивлялся
Alexander
если forever не течет, то forever $ forever уже течет
Alexander
это скорее к глобальным вопросам структуры кода
Alexander
под циклами понимаются не просто проход по матрице, но и такие конструкции
Alexander
абстрактно слишком..
Alexander
а про fix это как говорить, что анонимные функции это плохой тон
Alexander
Alexander
можно, а ещё в filter (>0) (>0) можно вынести в отдельную функцию
Alexander
я не спорю, в паскале так делали
Alexander
при желании в хаскеле можно и без именованных переменных писать, но никто так не делает
Alexander
есть определенная сложность куска кода, при достижении которой ее надо скрывать
Alexander
и я с вами не согласен, что она тут достигнута
Alexander
fix (\f cursOp -> do
result <- liftIO $ mdb_cursor_get cursOp cur pkey pval
when result $ do
yieldKey pkey
f MDB_NEXT_NODUP
) MDB_FIRST
делать такие штуки через вынесение в отдельную функцию - я тоже смысла не вижу
Alexander
а это уже другой вопрос. Если бы мы писали код вместе, она бы была достигнута из соображений удобства командной работы
Alexander
или мы бы не работали вместе ;)
Alexander
как вариант :)
Alexander
вроде в команде ни у кого проблем с fix никогда не возникало
Alexander
mdo rec do уже крайне редко используется, это да
Denis
Когда вы fix юзаете? Мне приходилось примерно никогда.
Alexander
где делается завязывание узлов, там далеко не все просто становится, с другой стороны простым вынесением вспомогательных функций это не решается
Alexander
@catamorphism для анонимных циклов например, чтобы всякую чушь в хелперы не выносить
Alexander
александр, а вы пользуетесь метриками типа цикломатической сложности при работе?
Alexander
нет
parket
Alexander
+
Alexander
@catamorphism я могу сказать, что fix используется редко, но с утверждением про стиль, я не могу согласиться ну никак
Denis
я цикломатической сложностью даже не пытаюсь пользоваться после того как мне какая-то тулза количество веток в case поскладывала в значение для этой метрики
Alexander
я повторю свое утверждение, если вдруг я увижу код, который по моему внутренему чувству стиля становится лучше за счет его использования, я ничего против fix иметь не буду
Alexander
раз уж тут заговорили про цикломатическойю стожность, то я буду рад увидеть доказательстно, что для вспомогательной функции именованной функции и для fix она будет отличаться
Alexander
в js есть серьезная разница между стрелочными и именованными функциями
Alexander
там это как раз оправданно
Alexander
т.к. делают они одно и тоже, только вспомогательная фунция ещё и в контексте доступна, в отличии от анонимной
parket
Alexander
и для неё применимы все оптимизации, которые бы хорошо чтобы были корректными
Alexander
Alexander
если я тип анонимной напишу, тоже перестанет считаться?
Alexander
и комментарий что она делает
Alexander
но да, перестанет
Alexander
надо рассказать императивным ребятам, что они должны так со всеми циклами делать
Alexander
собственно, использование именованной функции вместо комментария это уже исключительно вопрос вкуса
Alexander
у меня сейчас по основной работе императивные ребята, успешно им рассказываю что делать чтобы упрощать вложенные циклы на примере
кана
раньше никогда не использовал fix, но в этот раз точно буду
кана
жаль что раньше не понимал как его использовать
кана
Alexander
Alexander
ну вот тут большого смысла нету, разве что worker/wrapper порадовать
Alexander
чем люди в низкоуровневом коде иногда занимаются
кана
ты мне?
parket
Alexander
@kana_sama ага
Alexander
а почкему не
map f [] = []
map f (x:xs) = f x : map f xs
Зигохистоморфный
это очевидно, потому что foldr может быть выражен через fix и fix через foldr
ну и map/filter может быть выражен через foldr, а значит и через fix
кана
смысл тут простой, как выше сказали - удобно использовать для анонимной рекурсии
кана
зачем делать именованную рекурсию когда можно не делать)
Alexander
рекурсия может быть эффективнее
Alexander
ну и в хорошем случае аллокаций чуть больше с fix