?

Log in

No account? Create an account
Code review - Лямбда - функциональное программирование [entries|archive|friends|userinfo]
Лямбда - функциональное программирование

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Code review [Nov. 28th, 2011|06:47 pm]
Лямбда - функциональное программирование

ru_lambda

[kkirsanov]
[Tags|]

После длительных блужданий вокруг да около начал писать подсобные скрипты на хаскеле, а не на питоне.

Вот первое детище: https://gist.github.com/1400214 - работать то работает, но хотелось бы получить комментарии по стилю написания и потенциальным ошибкам.

Делает следующее: читает список номеров из файла, делает по каждому номеру запрос, строит частотный словарь ответов.
linkReply

Comments:
From: fuckind3r
2011-11-28 03:05 pm (UTC)
showFreq tupl = f (fst tupl)  ++ ":" ++ (show $ snd tupl)
  f str =  filter (\x-> not (elem x "\n")) str
->
showFrex (a,b) = filter (/='\n') $ printf "%s:%d" a b
-- или тут можно просто использовать show на строку, 
-- чтобы \n и прочие спецсимволы эскейпировались.

case Map.lookup word freq of
  Nothing -> Map.insert word 1 freq
  Just x -> Map.insert word (x+1) freq
->
Map.insertWith (+1) 1 word freq

В общем-то, нормально все. Просто чуток не хватает знания библиотек.
(Reply) (Thread)
[User Picture]From: jakobz
2011-11-28 03:21 pm (UTC)
Всю функцию updateFreq можно переписать как:
updateFreq freq word = Map.insertWith (+) word 1 freq

(Reply) (Thread)
[User Picture]From: jakobz
2011-11-28 03:27 pm (UTC)
Еще можно вот здесь сразу строку склеить через unlines, вроде попроще будет:

let freq = Map.toList $ foldl updateFreq nullfreq userNames
mapM_ (\x -> (putStrLn $ showFreq x)) freq

типа так:

let freqs =
unlines
$ map showFreq
$ Map.toList
$ foldl updateFreq nullfreq userNames

print freqs
(Reply) (Parent) (Thread)
[User Picture]From: antilamer
2011-11-28 04:30 pm (UTC)
И никогда не надо использовать foldl - используйте foldl', ибо он не ленив (foldl - готовый рецепт утечки памяти).

Вместо Map.insertWith (+1) тоже стоит использовать Map.insertWith (\a -> a `seq` (a+1)) - практика показывает, что досюда strictness analysis не доходит.
(Reply) (Thread)
[User Picture]From: nikita_timofeev
2011-11-28 04:59 pm (UTC)
А как течёт память через ленивую свёртку?
(Reply) (Parent) (Thread)
[User Picture]From: antilamer
2011-11-28 05:35 pm (UTC)
Левая свёртка ничего не вычисляет, пока не форсанут результат - она строит терм вида ((((....((((....(u `f` x0) `f` x1) ........)))))

Течёт память на хранение этого терма (он ссылается на все иксы; память течет и поэтому тоже); а потом, когда он вычисляется, то течёт стек.
(Reply) (Parent) (Thread)
[User Picture]From: kkirsanov
2011-11-28 05:11 pm (UTC)
--И никогда не надо использовать foldl - используйте foldl', ибо он не ленив
дадада. читал об этом, но тут 9\10 времени перестраивал мозг на монады, так что максимально делал "как по книжке".
(Reply) (Parent) (Thread)
[User Picture]From: demmonoid
2011-11-28 05:37 pm (UTC)
Вот почему вы раньше молчали про foldl'? Я, как заправское быдло, использовал foldr, чтобы санки так не разрастались. :(
(Reply) (Parent) (Thread)
[User Picture]From: antilamer
2011-11-28 05:46 pm (UTC)
Я думал, все знают :(
(Reply) (Parent) (Thread)
[User Picture]From: nponeccop
2011-11-29 01:40 am (UTC)
ну фолдр всё-таки кошернее. если можно его - то и нужно
(Reply) (Parent) (Thread)
[User Picture]From: potan
2011-11-29 07:04 am (UTC)
А foldr чем плох?
(Reply) (Parent) (Thread)
From: ro-che.info
2011-11-28 10:36 pm (UTC)
1. ghc -O стирает разницу между foldl и foldl'. В данном случае, по крайней мере.
2. Про insertWith ты прав, strictness analysis не дойдет. Только твоя версия не поможет. Ну будет там вместо санка a+1 санк a `seq` (a+1) :)
Вместо этого надо использовать Map.insertWith'.
(Reply) (Parent) (Thread)
[User Picture]From: antilamer
2011-11-29 04:40 am (UTC)
1 - хм, не знал; кажется, раньше не стирал. Или это он для foldl (+) 0 [0..10000000] :: Integer не стирал..
2 - точно, ступил, спасибо.
(Reply) (Parent) (Thread)
[User Picture]From: nponeccop
2011-11-29 01:41 am (UTC)
Используйте HLint
(Reply) (Thread)
[User Picture]From: kkirsanov
2011-11-29 08:54 am (UTC)
О, спасибо. Отличная вещь.
(Reply) (Parent) (Thread)
[User Picture]From: afiskon
2011-11-29 06:41 am (UTC)
Нормальный код, читабельный.

Только не совсем ясно, чем пайтон не угодил (ни в коей мере его не защищаю, я вообще перловик). Или вы в тренировочных целях?
(Reply) (Thread)
[User Picture]From: kkirsanov
2011-11-29 08:58 am (UTC)
В тренировачных.
А то у же год читать читаю, а делать - не делаю.
(Reply) (Parent) (Thread)