Шаблон трансдуктор (transducer)

Сегодня я покажу один простой, но довольно практичный шаблон-преобразователь, сочетающий в себе массовый проход по некоторому набору данных и последующую компоновку этих данных либо в единый конгломерат, либо в единственное отображение из элементарного типа.

Данный шаблон, носит в некоторых кругах название transducer (т.е. массированный преобразователь данных) и пришел он в современное программирование из очень интересного и мощного языка программирования Clojure, где используется для обработки очень больших массивов данных.

Шаблон выглядит следующим образом:

auto transduce(alias f, alias g, Range)(Range range)
{
	import std.algorithm : map, reduce;
	return range
			.map!f
			.reduce!g;
}

Что интересно, применять его достаточно просто: необходимо определить (или построить in situ, т.е. на месте) две функции и подать их в шаблон вместе с данными, требующими обработки.

Вот простой пример использования, хотя применение шаблона ограничено только вашей фантазией и синтаксисом шаблона:

import std.conv : to;
import std.stdio;

void main()
{
	import std.algorithm;
	import std.range;


	auto arr = [1,2,3,4,5];
	arr
		.transduce!(a => to!float(a), 
				   (a,b) => a + b)
		.writeln;

	auto f(T)(T x)
	{
		return to!string(x);
	}

	arr
	   .transduce!("to!string(a)", (a,b) => a ~= b)
	   .writeln;
}

Насколько я знаю, это лишь один из вариантов transducer, один из многих, но возможное поле действий таких преобразований очень и очень велико, что вероятно, будет затронуто в одной из более масштабных статей блога или же в целой группе статей-рецептов…

Добавить комментарий