<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
	<title>Хабрахабр:  Метки / haskell</title>
	<link>http://habrahabr.ru/rss/tag/haskell/</link>
	<description><![CDATA[]]></description>
	<language>ru</language>
	<managingEditor>editor@habrahabr.ru</managingEditor>
	<generator>habrahabr.ru</generator>
	<pubDate>Sat, 11 Feb 2012 04:09:14 GMT</pubDate>
	<lastBuildDate></lastBuildDate>
	<image>
		<link>http://habrahabr.ru/</link>
		<url>http://habrahabr.ru/i/logo.gif</url>
		<title>Хабрахабр</title>
	</image>
	
			
		<item>		
			<title><![CDATA[Haskell / Расшифровка кода на языке Haskell (конкурс по ФП в январе 2012)]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/137116/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/137116/</link>			
			<description><![CDATA[Заголовок данной статьи является очень двусмысленным. Это станет понятно из дальнейшего изложения. Покамест лишь объявим, что сейчас мы опишем решение задачи <a href="http://users.livejournal.com/_darkus_/629943.html">конкурса по функциональному программированию</a>, который проводился в январе 2012 года. В качестве задачи почтенным участникам предлагалось расшифровать зашифрованный исходный код простейшим шифром на основе циклического применения ключа к тексту посредством операции XOR. В условиях задачи дополнительно сообщалось, что зашифрован код на языке Haskell, длина ключа не превышает 5 символов, а сам ключ состоит только из заглавных символов латинского алфавита.<br/>
<br/>
В итоге 17 претендентов на призы прислали свои решения, расшифровав исходник, запустив его и прислав правильный код, который этот исходник сгенерировал для участника. Из этих участников 16 получили призы (один прислал правильный ответ после завершения конкурса). Так что теперь остаётся посмотреть, что и как было в этом конкурсе.<br/>
<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/137116/#habracut">Ознакомиться подробней...</a> </div>]]></description>
			
			<pubDate>Fri, 27 Jan 2012 09:09:18 GMT</pubDate>
			<author>Darkus</author>
			<category>haskell</category><category>кодирование</category><category>декодирование</category><category>XOR-шифрование</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Утилита для работы с N-граммами]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/136775/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/136775/</link>			
			<description><![CDATA[В одной из своих предыдущих статей (<a href="http://habrahabr.ru/blogs/Haskell/135127/">«Реализация конструирования N-грамм и генерации псевдо ЕЯ-текста на их основе на языке Haskell»</a>) я рекомендовал читателю в качестве самостоятельного упражнения реализовать для построения N-грамм интерактивную среду. В сегодняшней заметке я покажу, как это можно сделать в виде консольного приложения на языке программирования Haskell. За основу мы возьмём эссе № 8 из моей книги <a href="http://www.twirpx.com/file/643353/">«14 занимательных эссе о языке Haskell и функциональном программировании»</a>, которое называется «Простой интерпретатор команд», но применим в этой статье немного монадического кун-фу.<br/>
<br/>
Прочитав данную статью, вы узнаете, как при помощи языка Haskell и функционального программирования дать ответы на следующие вопросы:<br/>
<ol>
<li>Как создавать свои собственные монады при помощи техники нанизывания имеющихся монад друг на друга посредством трансформаторов монад?</li>
<li>Как строить цикл интерпретации команд, в котором происходит распознавание введённой команды, её выполнение и вывод результатов (REP)?</li>
<li>Как в этом цикле «таскать» из функции в функцию изменяемое состояние, не прилагая для этого никаких усилий?</li>
<li>Как в любом месте цикла интерпретации бросать исключения и ловить их, обрабатывая красивым образом?</li>
<li>Как предоставлять пользователю возможность вводить команды в очень гибком режиме?</li>
</ol>Всё это позволит вам быстро и без особых усилий разрабатывать консольные приложения: серверные приложения, вопрос-ответные системы, интерактивные диалоговые игры и т. д.<br/>
<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/136775/#habracut">Хватит слов и обещаний, покажите код</a> </div>]]></description>
			
			<pubDate>Mon, 23 Jan 2012 04:00:47 GMT</pubDate>
			<author>Darkus</author>
			<category>haskell</category><category>N-граммы</category><category>интерпретация</category><category>монады</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Фреймворк для генерации рекурсивных сказок на языке Haskell]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/136007/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/136007/</link>			
			<description><![CDATA[Данная статья в какой-то мере является переработкой и улучшением эссе № 14 из моей книги <a href="http://www.twirpx.com/file/643353/">«14 занимательных эссе о языке Haskell и функциональном программировании»</a>. Статья посвящена генерации <i>рекурсивных</i> (или <i>кумулятивных</i>) сказок при помощи обобщённых функций, реализующих определённые паттерны рекурсии. Такие функции вместе со вспомогательными структурами данных и другими программными сущностями будут собраны во фреймворк для повторного использования при решении задач генерации естественно-языкового текста (ЕЯ-текста).<br/>
<br/>
Что такое «рекурсивная сказка»? Рекурсивная сказка — это сказка с повторяющимся сюжетом. Есть многое множество примеров рекурсивных сказок практически у всех народов мира, и учёные даже составили довольно-таки разветвлённую классификацию оных рекурсивных сказок. Есть сказки с простым перечислением (например, английское стихотворение «Дом, который построил Джек»), есть с двойным (например, русская народная сказка «Теремок», где при появлении каждого нового персонажа все предыдущие выходят и представляются). Есть сказки, где перечисляются сами действующие лица, а есть и такие, где одно действующее лицо перечисляет какие-либо предметы (например, сказка «Лисичка со скалочкой»), либо выполняет какие-либо повторяющиеся действия (сказка «Петушок и бобовое зёрнышко»). Такие сказки, по свидетельстам фольклористов, являются одними из самых древних, и отражают глубинные архетипы человеческой психики. Ну а их предназначение достаточно просто — успокоение детей повторяющимся ритмом повествования и обучения их базовому набору слов.<br/>
<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/136007/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Wed, 11 Jan 2012 08:13:57 GMT</pubDate>
			<author>Darkus</author>
			<category>haskell</category><category>ЕЯ-текст</category><category>генерация текста</category><category>рекурсивные сказки</category><category>кумулятивные сказки</category><category>рекурсия</category><category>паттерны рекурсии</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Реализация конструирования N-грамм и генерации псевдо ЕЯ-текста на их основе на языке Haskell]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/135127/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/135127/</link>			
			<description><![CDATA[Сего дня мы продолжим рассмотрение темы генерации естественноязыковых текстов, начатую в предыдущей моей статье <a href="http://habrahabr.ru/blogs/Haskell/134291/">«Генерация естественно-языковых фраз при помощи языка Haskell на основе порождающих грамматик и расширенных цепей Маркова»</a>. Возможно, что некоторым из вас сегодняшние вопросы покажутся несколько неприменимыми к теме синтеза ЕЯ-текста, однако в одно время этот подход широко обсуждался. Ну а использование статистических методов в лингвистике для анализа синтагматических отношений как использовалось, так и используется по сей день. Итак, речь поведём о так называемых N-граммах.<br/>
<br/>
<blockquote>N-грамма — непрерывная последовательность из <i>n</i> символов, взятых из заданной большей последовательности тех же символов. Под символами могут пониматься такие объекты, как буквы, фонемы, слоги, морфемы, слова, пары оснований ДНК и другие подобные объекты. Каждой N-грамме приписывается частная вероятность, подсчитанная на основе выборки всех возможных N-грамм из достаточно большого корпуса текстов (под «текстом» здесь понимается соответствующая последовательность объектов — собственно тексты, речь на естественном языке, геном и т. д.).</blockquote><br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/135127/#habracut">Ознакомиться с дальнейшим изложением</a> </div>]]></description>
			
			<pubDate>Sat, 24 Dec 2011 20:43:16 GMT</pubDate>
			<author>Darkus</author>
			<category>haskell</category><category>N-граммы</category><category>генерация текста</category><category>ЕЯ-текст</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Генерация естественно-языковых фраз при помощи языка Haskell на основе порождающих грамматик и расширенных цепей Маркова]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/134291/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/134291/</link>			
			<description><![CDATA[А что же, оставим пока на время описания решений всевозможных задач с конкурсов по функциональному программированию, а обратим свой взгляд на такую интересную тему, как генерация естественно-языкового текста. Одним из методов генерации ЕЯ-текста является использование порождающих грамматик, и он является довольно-таки универсальным, поскольку при должном уровне детализации грамматики и наполненности словарей позволяет генерировать произвольный ЕЯ-текст на заданную тему по внутреннему представлению смысла.<br/>
<br/>
Однако здесь мы рассмотрим лишь один из методов, к тому же скрещённый с расширенными цепями Маркова. Этот метод позволяет генерировать ЕЯ-текст только по заранее заготовленному шаблону, а разнообразие (мера сложности) вариантов достигается при помощи цепей Маркова. Шаблон, описываемый порождающей грамматикой, для каждого терма наполняется множествами возможных вариантов реализации терма в виде ЕЯ-слова или фразы, при этом каждому варианту реализации ставится в соответствие вероятность его проявления среди множества других вариантов реализации терма.<br/>
<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/134291/#habracut">Ознакомиться подробнее</a> </div>]]></description>
			
			<pubDate>Wed, 21 Dec 2011 10:58:38 GMT</pubDate>
			<author>Darkus</author>
			<category>haskell</category><category>цепи Маркова</category><category>генерация текста</category><category>порождающие грамматики</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Конструирование и вычисление арифметических выражений на языке Haskell]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/134290/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/134290/</link>			
			<description><![CDATA[Сего дня, уважаемые хабровчане, мы посмотрим, как при помощи языка высокого уровня Haskell решать такие занимательные задачи, как конструирование арифметических выражений из заданных чисел для получения целевых чисел. Так, например, на <a href="http://users.livejournal.com/_darkus_/618329.html">декабрьском конкурсе по функциональному программированию</a> всем желающим предлагалась такая задача:<br/>
<br/>
<blockquote><i>Даны числа 1, 5, 6 и 7. При помощи произвольного числа арифметических операций и скобок необходимо составить такое математическое выражение из этих чисел, чтобы его значение было равным 21. Данные числа можно использовать в выражении ровно по одному разу. Числа нельзя «склеивать» друг с другом (то есть из 1 и 5 нельзя получать 15 и т. п.).</i></blockquote>Давайте разработаем модуль на языке Haskell, в котором определены все необходимые для решения программные сущности.<br/>
<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/134290/#habracut">Перейти к описанию решения</a> </div>]]></description>
			
			<pubDate>Mon, 12 Dec 2011 20:05:25 GMT</pubDate>
			<author>Darkus</author>
			<category>haskell</category><category>арифметика</category><category>конструирование</category><category>вычисление</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / В поисках жирного (The Quest For FAT)]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/134432/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/134432/</link>			
			<description><![CDATA[При разработке некоего программно-аппаратного комплекса потребовалось создать клиентское устройство, которое для прочих устройств должно выглядеть как обычная USB-флешка, или если более формально, то USB Mass Storage Device. Необычность устройства в том, что оно должно имитировать для внешнего мира файловую систему FAT с файлами достаточно большого размера (2GB и и более), при том, что сами файлы на устройстве, конечно, отсутствуют и находятся в сети. Да и вообще это не файлы, а некие аудио-потоки.<br/>
<br/>
Задача, на первый взгляд, простая: на каждый запрос на чтение блока (команду SCSI) отдаем содержимое этого блока. Блок может либо принадлежать какому-нибудь из «файлов», либо содержать служебную информацию FAT.<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/134432/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Mon, 12 Dec 2011 08:40:38 GMT</pubDate>
			<author>voidlizard</author>
			<category>haskell</category><category>forth</category><category>embedded</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Фреймворк для решения задач о переправах на языке Haskell]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/134218/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/134218/</link>			
			<description><![CDATA[Сегодня мы рассмотрим, как при помощи языка Haskell можно построить небольшой фреймворк для решения занимательных задач о переправах. Эта задача была задана почтенной публике в <a href="http://users.livejournal.com/_darkus_/606254.html">октябрьском конкурсе по функциональному программированию</a> в своей классической формулировке:<br/>
<br/>
<img src="http://www.ljplus.ru/img4/_/d/_darkus_/11.jpg" alt="image" align="center"/><br/>
<blockquote><i>Крестьянину нужно перевезти через реку волка, козу и капусту. Но лодка такова, что в ней может поместиться только крестьянин, а с ним или один волк, или одна коза, или одна капуста. Но если оставить волка с козой, то волк съест козу, а если оставить козу с капустой, то коза съест капусту. Как перевёз свой груз крестьянин, если известно, что все переправились через реку в целости и сохранности?</i></blockquote><div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/134218/#habracut">Ознакомиться с решением</a> </div>]]></description>
			
			<pubDate>Thu, 08 Dec 2011 06:35:55 GMT</pubDate>
			<author>Darkus</author>
			<category>haskell</category><category>занимательные задачки</category><category>теория категорий</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Решение задачи о перегорающих лампочках на языке Haskell]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/133798/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/133798/</link>			
			<description><![CDATA[Своё первое эссе на Хаброхабре я хотел бы посвятить решению задачи, заданной мною на <a href="http://users.livejournal.com/_darkus_/612310.html">ноябрьском конкурсе по функциональному программированию</a>, который я традиционно устраиваю на ежемесячной основе в своей уютненькой жэжэшечке. Задача была такова:<br/>
<br/>
<blockquote><i>Дан индикатор, состоящий из <b>n</b> лампочек, которые могут гореть или не гореть. Дан алфавит из <b>k</b> символов, которые закодированы различными комбинациями горящих и не горящих лампочек на индикаторе. Необходимо определить <u>максимальное</u> число лампочек индикатора <b>p</b> (<nobr><b>p</b> &lt;= <b>n</b></nobr>) и указать эти лампочки, которые, если и перегорят, то не влияют на однозначное распознавание всех символов алфавита.</i></blockquote><div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/133798/#habracut">Описание решения</a> </div>]]></description>
			
			<pubDate>Thu, 01 Dec 2011 13:14:59 GMT</pubDate>
			<author>Darkus</author>
			<category>haskell</category><category>фп</category><category>конкурс</category><category>занимательная задачка</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Эндофункторы категории Hask и их моноидальная структура]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/133579/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/133579/</link>			
			<description><![CDATA[<h2>Введение</h2><br/>
В <a href="http://habrahabr.ru/blogs/Haskell/133277/">предыдущей статье</a> я рассказал о понятиях категории и функтора в контексте категории <b>Hask</b>, состоящей из типов данных и функций языка Haskell. Теперь я хочу рассказать о другом примере категории, построенном из уже известных нам понятий, а так же о весьма важном понятии моноида.<br/>
<br/>
<h2>Обозначения</h2><br/>
В прошлый раз я хотел обозначить морфизм/функцию буквой <code>f</code>, но она была занята для обозначения функтора/переменной типа <code>f</code> – никакой проблемы с точки зрения языка Haskell в этом нет, но при невнимательном прочтении это может вызвать путаницу, и я использовал для морфизма букву <code>g</code>. Пустяк, но всё же, я считаю, что полезно визуально разделять сущности, имеющие разную природу. Обычные типы я буду называть их обычными именами, а вот переменные типов я буду называть маленькими греческими буквами, причём простые (<code>∗</code>) – буквами из начала алфавита, а параметрические (<code>∗ → ∗</code>) – буквами из конца алфавита (<code>θ</code> не из конца, но она смотрится лучше, чем <code>χ</code>, которая слишком похожа на <code>X</code>). Итак, в терминологии категории <b>Hask</b>:<br/>
<ul>
<li>Объекты: <code> α, β, γ, δ ∷ ∗</code></li>
<li>Функторы: <code> θ, φ, ψ, ω ∷ ∗ → ∗</code></li>
<li>Морфизмы: <code> f, g, h ∷ α → β</code></li>
</ul> Ввиду того, что GHC довольно давно поддерживает unicode, эти обозначения ничего не меняют в отношении синтаксиса и носят чисто косметический характер.<br/>
<br/>
Ещё одно замечание, касательно терминологии: как вы уже заметили, то, что я в прошлый раз называл словом “кайнд” (kind), я теперь называю словом “сорт” – это считается общепринятым переводом.<br/>
<br/>
<h2>Категория с объектом Hask</h2><br/>
Давайте рассмотрим категорию, в которой будет только один объект – сама категория <b>Hask</b>. Что же будет морфизмами в такой категории? Это должны быть какие-то отображения <b>Hask</b> → <b>Hask</b>, и мы уже знаем такой тип отображений – это эндофункторы категории <b>Hask</b>, то есть типы сорта <code>∗ → ∗</code>, воплощения класса <code>Functor</code>. Теперь нужно продумать как устроены единичный морфизм и композиция в этой категории, так чтобы они удовлетворяли аксиомам. <div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/133579/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Tue, 29 Nov 2011 06:46:10 GMT</pubDate>
			<author>laughedelic</author>
			<category>haskell</category><category>category theory</category><category>category</category><category>Hask</category><category>functors</category><category>type systems</category><category>хаскель</category><category>теория категорий</category><category>функторы</category><category>типы данных</category><category>monoid</category><category>моноид</category>
		</item>
		
		
		
		
		
		
		
		
	
		
		
		
			
		<item>		
			<title><![CDATA[Haskell / [Перевод] Введение в Template Haskell. Часть 3. Прочие аспекты TH]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/133009/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/133009/</link>
			<description><![CDATA[<i>Данный текст является переводом <a href="http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3">документации Template Haskell</a>, написанной Булатом Зиганшиным. Перевод всего текста разбит на несколько логических частей для облегчения восприятия. Далее курсив в тексте — примечания переводчика. Предыдущие части:</i><br/>
<ul>
<li><a href="http://habrahabr.ru/blogs/Haskell/131998/">Часть 1. Необходимый минимум</a></li>
<li><a href="http://habrahabr.ru/blogs/Haskell/132679/">Часть 2. Инструменты цитирования кода</a></li>
</ul><br/>
<br/>
<h2>Материализация</h2><br/>
Материализация (reification) — это средство Template Haskell, позволяющее программисту получить информацию из таблицы символов компилятора. Монадическая функция <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#v:reify"><code>reify</code></a> <code>∷ Name → Q Info</code> возвращает информацию о данном имени: если это глобальный идентификатор (функция, константа, конструктор) – вы получите его тип, если это тип или класс – вы получите его структуру. Определение типа <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#t:Info"><code>Info</code></a> можно найти в модуле <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html"><code>Language.Haskell.TH.Syntax</code></a>.<br/>
Материализация может быть использована для того, чтобы получить структуру типа, но таким образом нельзя получить тело функции. Если вам нужно материализовать тело функции, то определение функции нужно процитировать и дальше можно будет работать с этим определением с помощью другого шаблона. Например так:<br/>
<pre><code>$(optimize [d| fib = … |])
</code></pre><br/>
или так<br/>
<pre><code>fib = $(optimize [| … |])
</code></pre><br/>
<i>На самом деле, в оригинальной статье больше ничего не говорится про материализацию. Не знаю, насколько это содержательная тема – необходимый минимум знаний о ней ограничивается функцией <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#v:reify"><code>reify</code></a> и типом <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#t:Info"><code>Info</code></a>, но есть некоторые тонкости, связанные например с тем, что можно получить информацию не о любом имени. Если эта тема интересна, я могу собрать какую-нибудь информацию и написать об этом отдельную заметку (или вклеить сюда).</i><br/>
<br/>
<h2>Облегчённое цитирование имён</h2><br/>
Чтобы получить имя (<code>∷ Name</code>), соответствующее интересующему идентификатору, можно использовать функцию <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#v:mkName"><code>mkName</code></a>, но это не безопасное решение, потому что <code>mkName</code> возвращает не квалифицированное имя, которое может интерпретироваться по-разному в зависимости от контекста. А вот код <code>VarE id ← [| foo |]</code> безопасен в этом смысле, так как цитирование квалифицирует имена (получится что-то типа <code>My.Own.Module.foo</code>), но этот код слишком многословный и требует монадический контекст для использования. К счастью, Template Haskell, имеет другую простую форму цитирования имён: <code>'foo</code> (одинарная кавычка перед <code>foo</code>) имеет тип <code>Name</code> и содержит квалифицированное имя, соответствующее идентификатору <code>foo</code>, так что код <code>let id = 'foo</code> эквивалентен по смыслу коду <code>VarE id ← [| foo |]</code>. Обратите внимание, что эта конструкция имеет простой тип <code>Name</code> (а не <code>Q Exp</code> или <code>Q Name</code>), так что она может быть использована там, где не возможно использование монад, например:<br/>
<pre><code>f ∷ Exp → Exp
f (App (Var m) e) |  m == 'map  =  …
</code></pre><br/>
Эта новая форма тем не менее является цитированием и подчиняется тем же правилам, что и цитирующие скобки <code>[| … |]</code>. Например, она не может быть использована внутри этих скобок (так нельзя: <code>[| 'foo |]</code>), <i>но и вклеивание к ней не может быть применено (так тоже нельзя: <code>$( 'foo )</code>), потому что для вклейки нужен тип <code>Q …</code></i>. Более важно то, что эта форма определяется статически, возвращая полностью квалифицированное имя, с однозначной интерпретацией.<br/>
Haskell’евские пространства имён немного всё усложняют. Цитата <code>[| P |]</code> означает конструктор данных <code>P</code>, в то время как <code>[t| P |]</code> означает конструктор типа <code>P</code>. Поэтому для “облегчённого цитирования” необходим такой же способ разделения этих сущностей. Для контекста типов используется просто две одинарные кавычки:<br/>
<ul>
<li><code>'Foo</code> означает “конструктор данных <code>Foo</code> в контексте выражения”</li>
<li><code>'foo</code> означает “имя <code>foo</code> в контексте выражения”</li>
<li><code>''Foo</code> означает “конструктор типа <code>Foo</code> в контексте типов”</li>
<li><code>''foo</code> означает “переменная типа <code>foo</code> в контексте типов”</li>
</ul> Облегчённая форма цитирования используется в примере генерации воплощений класса <code>Show</code>, который разбирается в конце.<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/133009/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Mon, 21 Nov 2011 09:07:54 GMT</pubDate>
			<author>laughedelic</author>
			<category>Haskell</category><category>Template Haskell</category><category>meta-programming</category><category>хаскель</category><category>мета-программирование</category>
		</item>
		
		
		
		
		
	
		
		
		
			
		<item>		
			<title><![CDATA[Haskell / [Перевод] Введение в Template Haskell. Часть 2. Инструменты цитирования кода]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/132679/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/132679/</link>
			<description><![CDATA[<i>Данный текст является переводом <a href="http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3">документации Template Haskell</a>, написанной Булатом Зиганшиным. Перевод всего текста разбит на несколько логических частей для облегчения восприятия. Далее курсив в тексте — примечания переводчика. Другие части:</i><br/>
<ul>
<li><a href="http://habrahabr.ru/blogs/Haskell/131998/">Часть 1. Необходимый минимум</a></li>
<li><a href="http://habrahabr.ru/blogs/Haskell/133009/">Часть 3. Прочие аспекты TH</a></li>
</ul><br/>
<br/>
<h2>Монада цитирования</h2><br/>
Поскольку шаблоны должны возвращать свои значения обёрнутыми в монаду <code>Q</code>, для этого имеется набор вспомогательных функций, которые “поднимают” (оборачивают в <code>Q</code>) конструкторы типов <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#t:Exp"><code>Exp</code></a>, <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#t:Lit"><code>Lit</code></a>, <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#t:Pat"><code>Pat</code></a>: <code>lamE</code> (соотв. <code>LamE</code>), <code>varE</code>, <code>appE</code>, <code>varP</code> и т.д. В их сигнатурах так же используются переобозначенные поднятые типы: <code>ExpQ = Q Exp</code>, <code>LitQ = Q Lit</code>, <code>PatQ = Q Pat</code>… (все их можно найти в модуле <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Lib.html"><code>Language.Haskell.TH.Lib</code></a>). Используя эти функции, можно значительно сократить код, реже используя do-синтаксис.<br/>
В TH также есть функция <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#v:lift"><code>lift</code></a>, которая поднимает до <code>Q Exp</code> значение любого типа из класса <code>Lift</code>.<br/>
В некоторых редких случаях, вам может понадобиться не генерация уникального имени, а использование точного имени идентификатора из внешнего <i>(по отношению к шаблону)</i> кода. Для этих целей есть (чистая) функция <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Syntax.html#v:mkName"><code>mkName</code></a> <code>∷ String → Name</code>. Есть также вспомогательная функция <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/template-haskell-2.6.0.0/Language-Haskell-TH-Lib.html#v:dyn"><code>dyn</code></a> <code>s = return (VarE (mkName s))</code>, которая возвращает значение <code>Exp</code> представляющее переменную с данным именем (<code>dyn ∷ String → Q Exp</code>).<br/>
<br/>
<h2>Цитирующие скобки</h2><br/>
Построение значений <code>Exp</code>, представляющих абстрактное синтаксическое дерево — трудоёмкая и скучная работа. Но к счастью, в Template Haskell есть цитирующие скобки, которые преобразуют конкретный Haskell-код в структуру, представляющую его. <div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/132679/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Tue, 15 Nov 2011 21:20:19 GMT</pubDate>
			<author>laughedelic</author>
			<category>Haskell</category><category>Template Haskell</category><category>meta-programming</category><category>хаскель</category><category>мета-программирование</category>
		</item>
		
		
		
		
		
	
		
		
		
			
		<item>		
			<title><![CDATA[Haskell / [Перевод] Введение в Template Haskell. Часть 1. Необходимый минимум]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/131998/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/131998/</link>
			<description><![CDATA[<i>Данный текст является переводом <a href="http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3">документации Template Haskell</a>, написанной Булатом Зиганшиным. Перевод всего текста разбит на несколько логических частей для облегчения восприятия. Далее курсив в тексте — примечания переводчика.</i><br/>
<br/>
<a href="http://www.haskell.org/haskellwiki/Template_Haskell">Template Haskell</a> (далее TH) — это расширение языка Haskell предназначенное для мета-программирования. Оно даёт возможность алгоритмического построения программы на стадии компиляции. Это позволяет разработчику использовать различные техники программирования, не доступные в самом Haskell’е, такие как, макро-подобные расширения, направляемые пользователем оптимизации (например inlining), обобщённое программирование (polytypic programming), генерация вспомогательных структур данных и функций из имеющихся. К примеру, код<br/>
<pre><code class="bash">yell file line = fail ($(printf &quot;Error in file %s line %d&quot;) file line)</code></pre><br/>
может быть преобразован с помощью TH в<pre><code class="bash">yell file line = fail ((\x1 x2 -&gt; &quot;Error in file &quot;++x1++&quot; line &quot;++show x2) file line)</code></pre><br/>
Другой пример, код<br/>
<pre><code class="bash">data T = A Int String | B Integer | C
$(deriveShow ''T)
</code></pre><br/>
может быть преобразован в<pre><code class="bash">data T = A Int String | B Integer | C
instance Show T
    show (A x1 x2) = &quot;A &quot;++show x1++&quot; &quot;++show x2
    show (B x1)    = &quot;B &quot;++show x1
    show C         = &quot;C&quot;
</code></pre><br/>
В TH код на Haskell’е генерируется обычными Haskell’евскими функциями <i>(которые я буду для ясности называть шаблонами)</i>. Минимум того, что вам необходимо знать, чтобы использовать TH — это следующие темы:<br/>
<ol>
<li>Как Haskell-код представляется в шаблонах (TH-функциях)</li>
<li>Как монада цитирования используется для унификации имён</li>
<li>Как сгенерированный TH-код вставляется в программу</li>
</ol><div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/131998/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Fri, 11 Nov 2011 04:19:27 GMT</pubDate>
			<author>laughedelic</author>
			<category>Haskell</category><category>Template Haskell</category><category>meta-programming</category><category>хаскель</category><category>мета-программирование</category>
		</item>
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Ленивые вычисления]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/131910/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/131910/</link>			
			<description><![CDATA[Одной из «визитных карточек» Хаскеля являются отложенные, или ленивые, вычисления. Эта особенность языка не только открывает множество возможностей, но и создаёт некоторые проблемы, особенно со скоростью работы программ.<br/>
<br/>
В этой статье я постараюсь объяснить: что такое ленивые вычисления, для чего они могут применяться и как избежать потери производительности при их использовании.<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/131910/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Fri, 04 Nov 2011 15:01:35 GMT</pubDate>
			<author>savask</author>
			<category>haskell</category><category>хаскель</category><category>ленивые вычисления</category>
		</item>
		
		
		
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / Динамическое программирование и ленивые вычисления]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/130945/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/130945/</link>			
			<description><![CDATA[<a href="http://ru.wikipedia.org/wiki/%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5">Динамическое программирование</a> является довольно важным подходом в решении многих сложных задач, основанным на разбиении задачи на подзадачи и решении этих подзадач единожды, даже если они являются частью нескольких других подзадач. Перед людьми, которые только начинают овладевать функциональным программированием часто возникает вопрос: «<i>как избежать повторного решения подзадач, если не использовать переменные для сохранения результатов?</i>». В этом вопросе одна особенность функционального программирования — отсутствие переменных — мешает кешировать результаты решения подзадач, но другая особенность поможет — ленивые вычисления.<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/130945/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Fri, 21 Oct 2011 15:06:51 GMT</pubDate>
			<author>atamur</author>
			<category>haskell</category><category>динамическое программирование</category><category>ленивые вычисления</category>
		</item>
		
		
		
		
		
		
		
		
	
		
		
		
			
		<item>		
			<title><![CDATA[Haskell / [Перевод] Еще Одно Руководство по Монадам (часть 4: Монада Maybe и монада списка)]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/129909/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/129909/</link>
			<description><![CDATA[By Mike Vanier<br/>
<br/>
В предыдущих статьях этой серии мы изучали концептуальный базис монад, но обсуждение наше было слишком абстрактным. Теперь, когда вы, я надеюсь, поняли, что монады такое и для чего они нужны, пришло время для детального рассмотрения специфических монад. Это значит, что мы определим корректные воплощения класса типов <font color="blue">Monad</font> для множества различных понятий вычислений, которые мы увидели раньше. Мы используем наши знания, чтобы получить монадическую композицию в каждом конкретном случае через монадическое применение (оператор <font color="blue">&gt;&gt;=</font>), и с помощью монадных законов мы выведем определение <font color="blue">return</font>.<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/129909/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Fri, 07 Oct 2011 03:11:37 GMT</pubDate>
			<author>graninas</author>
			<category>haskell</category><category>монада</category><category>руководство</category><category>еще одно руководство по монадам</category><category>yet another monad tutorial</category>
		</item>
		
		
		
		
		
	
			
		<item>		
			<title><![CDATA[Haskell / JQuery-UI внутри бинарника]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/128705/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/128705/</link>			
			<description><![CDATA[У программ на хаскеле есть одно свойство. После компиляции мы получаем самодостаточный бинарник, один файл с исполняемым машинным кодом. Языков с компиляторами, удобных для веб разработки, не так уж и много. Это свойство не имеет особого значения. Однако, оно позволяет добиться непревзойдённого удобства установки программ. И не только установки, но и всего того, что скрывается за английским словом <i>deployment</i>.<br/>
<br/>
Веб-приложения используют дополнительные данные — изображения, стили css, скрипты javascript. Как правило они хранятся отдельно от исполняемого кода приложения в файловой системе веб-сервера. Но если этих дополнительных ресурсов меньше мегабайта — почему бы не встроить их прямо в бинарник? Сделаем deployment веб-приложений проще!<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/128705/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Mon, 19 Sep 2011 09:56:14 GMT</pubDate>
			<author>tranquil</author>
			<category>haskell</category><category>jquery</category><category>web</category><category>happstack</category><category>iptadmin</category>
		</item>
		
		
		
		
		
		
		
		
	
		
		
		
			
		<item>		
			<title><![CDATA[Haskell / [Перевод] Изучай Хаскель ради добра! Моноиды]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/128586/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/128586/</link>
			<description><![CDATA[Привет! Поздравляю всех с пятницей!<br/>
<br/>
Сегодня я хочу вам представить <a href="http://arsanukaev.blogspot.com/2011/09/monoid.html">мой очередной перевод гдавы <i>Моноиды</i></a> из учебника <a href="http://nostarch.com/lyah.htm">Learn You a Haskell for Great Good!</a>, который является продолжением <a href="http://habrahabr.ru/blogs/Haskell/123767/">предыдущего поста</a>.<br/>
<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/128586/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Fri, 16 Sep 2011 15:29:08 GMT</pubDate>
			<author>kingpin</author>
			<category>haskell</category><category>lyah</category><category>хаскель</category><category>программирование</category><category>функциональное программирование</category><category>учебник</category><category>моноиды</category><category>перевод</category>
		</item>
		
		
		
		
		
	
		
		
		
			
		<item>		
			<title><![CDATA[Haskell / [Перевод] Еще Одно Руководство по Монадам (часть 3: Монадные Законы)]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/128538/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/128538/</link>
			<description><![CDATA[By Mike Vanier<br/>
<br/>
В прошлой статье я рассказал о двух фундаментальных монадических операциях класса типов <font color="blue">Monad</font>: оператор связывания (bind, <font color="blue">&gt;&gt;=</font>) и функция <font color="blue">return</font>. В этой статье я закончу с определением класса типов <font color="blue">Monad</font> и расскажу о монадных законах.<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/128538/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Thu, 15 Sep 2011 23:13:06 GMT</pubDate>
			<author>graninas</author>
			<category>haskell</category><category>монада</category><category>руководство</category><category>еще одно руководство по монадам</category><category>yet another monad tutorial</category>
		</item>
		
		
		
		
		
	
		
		
		
			
		<item>		
			<title><![CDATA[Haskell / [Перевод] Еще Одно Руководство по Монадам (часть 2: функции &gt;&gt;= и return)]]></title>
			<guid isPermaLink="true">http://habrahabr.ru/blogs/Haskell/128070/</guid>
			<link>http://habrahabr.ru/blogs/Haskell/128070/</link>
			<description><![CDATA[By Mike Vanier<br/>
<br/>
<h4>Две фундаментальные монадические операции</h4><br/>
Помните, я говорил, что монады обобщают композицию и применение функций? Вот об этом здесь и поговорим. Наберитесь терпения, нам потребуется какое-то время.<br/>
<br/>
К этому моменту, я надеюсь, у вас сложилось хотя бы смутное ощущение монад, что они такое и для чего используются. Я уже упоминал одну из особенностей функционального программирования — композицию функций, благодаря которой мы создаем новые функции, объединяя старые. Функциональные программисты постоянно говорят о «комбинируемости» {1}, подразумевая, что если что-то в языке программирования не комбинируется, значит, оно немногого стоит. Аналогично, наши новоявленные монадические функции не были столь же полезны, если бы они не компоновались так, как это есть на самом деле. Но мы еще увидим, для их композиции нельзя использовать стандартную функцию «точка» (.) языка Haskell. Мы придем к выводу, что тут нужно что-то большее, и определим две фундаментальные монадические операции (или, для начала, их типы).<br/>
<div class="habracut"> <a class="habracut" href="http://habrahabr.ru/blogs/Haskell/128070/#habracut">Читать дальше &rarr;</a> </div>]]></description>
			
			<pubDate>Fri, 09 Sep 2011 06:53:58 GMT</pubDate>
			<author>graninas</author>
			<category>haskell</category><category>монада</category><category>руководство</category><category>еще одно руководство по монадам</category><category>yet another monad tutorial</category>
		</item>
		
		
		
		
		
	
	
	
	
	
	
	
	

	
</channel>
</rss>

