В последнее время увлекся функциональным программированием, в частности, изучил Erlang, продолжаю изучать Haskell, посмотрел реализацию этой парадигмы в Python. Задумался, а не решить одну какую-нибудь простенькую задачку прикладного характера, используя всё вышеперечисленное. Наткнулся на такую (пример 1).
Реализация решений приведена нижеErlang
% функция round модуля erlang округляет до целого числа
tround(Number, Precision) ->
P = math:pow(10, Precision),
round(Number * P) / P.
otp() ->
% определим структуру данных в виде списка кортежей
Data = [{1, 2500, 2.84},
{2, 15000, 29.3},
{3, 15000, 29.3},
{4, 15000, 29.3},
{5, 12857.14, 25.39},
{6, 15000, 29.3},
{7, 15000, 29.3},
{8, 15000, 29.3},
{9, 15000, 29.3},
{10, 15000, 29.3},
{11, 15000, 29.3},
{12, 15000, 29.3}],
Tuple_res = otp_acc(Data, {0, 0}),
K = 28,
tround(tround(element(1, Tuple_res) / element(2, Tuple_res), 2)*K, 2).
% в Erlang нельзя применить свертку к кортежу - воспользуемся рекурсией
otp_acc([], {S1, S2}) -> {S1, S2};
otp_acc([Head|Tail], {S1, S2}) -> otp_acc(Tail, {S1+element(2, Head), S2+element(3, Head)}).
Вывод: Рекурсия - неотъемлемая часть функционального программирования.
Haskell
-- функция round модуля Prelude округляет до целого числа
tround :: Double -> Int -> Double
tround n p = (fromInteger $ round $ n * (10^p)) / (10.0^^p)
otp :: Double
otp =
let
ldata = [(1, (2500, 2.84)),
(2, (15000, 29.3)),
(3, (15000, 29.3)),
(4, (15000, 29.3)),
(5, (12857.14, 25.39)),
(6, (15000, 29.3)),
(7, (15000, 29.3)),
(8, (15000, 29.3)),
(9, (15000, 29.3)),
(10, (15000, 29.3)),
(11, (15000, 29.3)),
(12, (15000, 29.3))]
z = foldl(\acc x -> (fst(acc) + fst(snd(x)), snd(acc) + snd(snd(x)))) (0,0) ldata
k = 28
in tround ((tround (fst(z)/snd(z)) 2) * k) 2
Вывод: Свертка с кортежем - это потрясающе.
Python 2.x
data = {1: (2500, 2.84),
2: (15000, 29.3),
3: (15000, 29.3),
4: (15000, 29.3),
5: (12857.14, 25.39),
6: (15000, 29.3),
7: (15000, 29.3),
8: (15000, 29.3),
9: (15000, 29.3),
10: (15000, 29.3),
11: (15000, 29.3),
12: (15000, 29.3)}
def otp():
k = 28
tuple_res = reduce(lambda res, d: (res[0] + d[0], res[1] + d[1]), data.values(), (0,0))
return round(tuple_res[0] / tuple_res[1], 2)*k
Вывод: Вполне лаконичное решение. Жаль, что Python постепенно уходит от парадигмы функционального программирования в общем модуле.
Комментариев нет:
Отправить комментарий