<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Chemist's Blog]]></title>
  <link href="http://chemist.github.com/atom.xml" rel="self"/>
  <link href="http://chemist.github.com/"/>
  <updated>2014-05-26T22:45:49+04:00</updated>
  <id>http://chemist.github.com/</id>
  <author>
    <name><![CDATA[Smirnov Alexey]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Cloud Haskell]]></title>
    <link href="http://chemist.github.com/blog/2014/05/26/cloud-haskell/"/>
    <updated>2014-05-26T21:43:00+04:00</updated>
    <id>http://chemist.github.com/blog/2014/05/26/cloud-haskell</id>
    <content type="html"><![CDATA[<p>Сегодня увидел что обновились версии пакетов для Cloud Haskell Platform.
В hackage изменения пока не попали, судя по всему готовят документацию.
Пока суть да дело, полез посмотреть по коду что нового.</p>

<!-- more -->


<p>В наборе теперь:</p>

<h2>Genserver</h2>

<p>Сильно смахивает на аналог из OTP, но естественно со своей спецификой, API простое, уже есть примеры в документации.</p>

<h2>Supervisor</h2>

<p>Аналогично, только пока нет документации, нужно смотреть код.
Что реализованно можно глянуть в <a href="https://github.com/haskell-distributed/distributed-process-platform/blob/master/src/Control/Distributed/Process/Platform/Supervisor.hs">шапке</a></p>

<h2>Message Exchanges</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="c1">--</span>
</span><span class='line'><span class="c1">-- The concept of a /message exchange/ is borrowed from the world of</span>
</span><span class='line'><span class="c1">-- messaging and enterprise integration. The /exchange/ acts like a kind of</span>
</span><span class='line'><span class="c1">-- mailbox, accepting inputs from /producers/ and forwarding these messages</span>
</span><span class='line'><span class="c1">-- to one or more /consumers/, depending on the implementation&#39;s semantics.</span>
</span><span class='line'><span class="c1">--</span>
</span><span class='line'><span class="c1">-- This module provides some basic types of message exchange and exposes an API</span>
</span><span class='line'><span class="c1">-- for defining your own custom /exchange types/.</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>Из коробки broadcast, router, custom.
Документация в процессе, смотреть <a href="https://github.com/haskell-distributed/distributed-process-platform/blob/master/src/Control/Distributed/Process/Platform/Execution/Exchange.hs">код</a>.</p>

<h2>EventManager</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="c1">-- The /EventManager/ is a parallel/concurrent event handling tool, built on</span>
</span><span class='line'><span class="c1">-- top of the /Exchange API/. Arbitrary events are published to the event</span>
</span><span class='line'><span class="c1">-- manager using &#39;notify&#39;, and are broadcast simulataneously to a set of</span>
</span><span class='line'><span class="c1">-- registered /event handlers/.</span>
</span></code></pre></td></tr></table></div></figure>


<p><a href="https://github.com/haskell-distributed/distributed-process-platform/blob/master/src/Control/Distributed/Process/Platform/Execution/EventManager.hs">код</a></p>

<h2>SystemLog</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="c1">-- This module provides a general purpose logging facility, implemented as a</span>
</span><span class='line'><span class="c1">-- distributed-process /Management Agent/. To start the logging agent on a</span>
</span><span class='line'><span class="c1">-- running node, evaluate &#39;systemLog&#39; with the relevant expressions to handle</span>
</span><span class='line'><span class="c1">-- logging textual messages, a cleanup operation (if required), initial log</span>
</span><span class='line'><span class="c1">-- level and a formatting expression.</span>
</span></code></pre></td></tr></table></div></figure>


<p><a href="https://github.com/haskell-distributed/distributed-process-platform/blob/master/src/Control/Distributed/Process/Platform/Service/SystemLog.hs">код</a></p>

<h2>Registry</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="c1">-- The module provides an extended process registry, offering slightly altered</span>
</span><span class='line'><span class="c1">-- semantics to the built in @register@ and @unregister@ primitives and a richer</span>
</span><span class='line'><span class="c1">-- set of features:</span>
</span><span class='line'><span class="c1">--</span>
</span><span class='line'><span class="c1">-- * Associate (unique) keys with a process /or/ (unique key per-process) values</span>
</span><span class='line'><span class="c1">-- * Use any &#39;Keyable&#39; algebraic data type as keys</span>
</span><span class='line'><span class="c1">-- * Query for process with matching keys / values / properties</span>
</span><span class='line'><span class="c1">-- * Atomically /give away/ names</span>
</span><span class='line'><span class="c1">-- * Forceibly re-allocate names to/from a third party</span>
</span><span class='line'><span class="c1">--</span>
</span><span class='line'><span class="c1">-- [Subscribing To Registry Events]</span>
</span><span class='line'><span class="c1">--</span>
</span><span class='line'><span class="c1">-- It is possible to monitor a registry for changes and be informed whenever</span>
</span><span class='line'><span class="c1">-- changes take place. All subscriptions are /key based/, which means that</span>
</span><span class='line'><span class="c1">-- you can subscribe to name or property changes for any process, so that any</span>
</span><span class='line'><span class="c1">-- property changes matching the key you&#39;ve subscribed to will trigger a</span>
</span><span class='line'><span class="c1">-- notification (i.e., regardless of the process to which the property belongs).</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Monitoring</h2>

<p>Мониторинг нод</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="c1">-- This module provides a primitive node monitoring capability, implemented as</span>
</span><span class='line'><span class="c1">-- a /distributed-process Management Agent/. Once the &#39;nodeMonitor&#39; agent is</span>
</span><span class='line'><span class="c1">-- started, calling &#39;monitorNodes&#39; will ensure that whenever the local node</span>
</span><span class='line'><span class="c1">-- detects a new network-transport connection (from another cloud haskell node),</span>
</span><span class='line'><span class="c1">-- the caller will receive a &#39;NodeUp&#39; message in its mailbox. If a node</span>
</span><span class='line'><span class="c1">-- disconnects, a corollary &#39;NodeDown&#39; message will be delivered as well.</span>
</span></code></pre></td></tr></table></div></figure>


<h2>BlockingQueue</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="c1">-- A simple bounded (size) task queue, which accepts requests and blocks the</span>
</span><span class='line'><span class="c1">-- sender until they&#39;re completed. The size limit is applied to the number</span>
</span><span class='line'><span class="c1">-- of concurrent tasks that are allowed to execute - if the limit is 3, then</span>
</span><span class='line'><span class="c1">-- the first three tasks will be executed immediately, but further tasks will</span>
</span><span class='line'><span class="c1">-- then be queued (internally) until one or more tasks completes and</span>
</span><span class='line'><span class="c1">-- the number of active/running tasks falls within the concurrency limit.</span>
</span><span class='line'><span class="c1">--</span>
</span><span class='line'><span class="c1">-- Note that the process calling &#39;executeTask&#39; will be blocked for _at least_</span>
</span><span class='line'><span class="c1">-- the duration of the task itself, regardless of whether or not the queue has</span>
</span><span class='line'><span class="c1">-- reached its concurrency limit. This provides a simple means to prevent work</span>
</span><span class='line'><span class="c1">-- from being submitted faster than the server can handle, at the expense of</span>
</span><span class='line'><span class="c1">-- flexible scheduling.</span>
</span><span class='line'><span class="c1">--</span>
</span></code></pre></td></tr></table></div></figure>


<p>Туда же Asunc, Timer, Time, и различные хэлперы.
Не знаю как кому, но мне API в том виде что уже есть, нравится.</p>

<p>К сожалению времени на попробовать в ближайшие 2 недели у меня не предвидится,
буду заниматься плановым переносом сервисов в другой датацентр.</p>

<p>Для желающих затестить, help по установке:
ghc-7.6.3</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>mkdir cloud
</span><span class='line'><span class="nb">cd </span>cloud
</span><span class='line'>git clone git@github.com:haskell-distributed/rank1dynamic.git
</span><span class='line'>git clone git@github.com:haskell-distributed/network-transport.git
</span><span class='line'>git clone git@github.com:haskell-distributed/distributed-static.git
</span><span class='line'>git clone git@github.com:haskell-distributed/distributed-process.git
</span><span class='line'>git clone git@github.com:haskell-distributed/distributed-process-platform.git
</span><span class='line'>
</span><span class='line'><span class="nb">cd </span>rank1dynamic
</span><span class='line'>cabal sandbox init --sandbox<span class="o">=</span>../.sandbox
</span><span class='line'>cabal install
</span><span class='line'>
</span><span class='line'><span class="nb">cd</span> ../network-transport
</span><span class='line'>cabal sandbox init --sandbox<span class="o">=</span>../.sandbox
</span><span class='line'>cabal install
</span><span class='line'>
</span><span class='line'><span class="nb">cd</span> ../distributed-static
</span><span class='line'>cabal sandbox init --sandbox<span class="o">=</span>../.sandbox
</span><span class='line'>cabal install
</span><span class='line'>
</span><span class='line'><span class="nb">cd</span> ../distributed-process
</span><span class='line'>cabal sandbox init --sandbox<span class="o">=</span>../.sandbox
</span><span class='line'>cabal install
</span><span class='line'>
</span><span class='line'><span class="nb">cd</span> ../distributed-process-platform
</span><span class='line'>cabal sandbox init --sandbox<span class="o">=</span>../.sandbox
</span><span class='line'>cabal install
</span><span class='line'>
</span><span class='line'>cabal repl
</span></code></pre></td></tr></table></div></figure>


<p></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Юмор]]></title>
    <link href="http://chemist.github.com/blog/2014/01/16/iumor/"/>
    <updated>2014-01-16T22:29:00+04:00</updated>
    <id>http://chemist.github.com/blog/2014/01/16/iumor</id>
    <content type="html"><![CDATA[<h2>Что за хаскель и что такое монада?</h2>

<!-- more -->


<h2>Хаскель</h2>

<p><img class="[photo]" src="http://chemist.github.com/images/haskell.jpg" title="[640] [480] [haskell cat]" ></p>

<p>Кота зовут Хаскель, порода мэйнкун, вес от 8 до 9,5 килограммов, возраст полтора года.</p>

<h2>Монада</h2>

<p><img class="[photo]" src="http://chemist.github.com/images/monad.jpg" title="[640] [480] [cafe monada]" ></p>

<p>Кафе в селе Поляна (Свалявский район, Закарпатье), откуда взялось название никто не знает.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Update: Морфология]]></title>
    <link href="http://chemist.github.com/blog/2013/07/31/update-morfologhiia/"/>
    <updated>2013-07-31T23:38:00+04:00</updated>
    <id>http://chemist.github.com/blog/2013/07/31/update-morfologhiia</id>
    <content type="html"><![CDATA[<p>Добрались руки и набросал новую версию морфологии.</p>

<!-- more -->


<p>Теперь в качестве структуры для хранения словаря используется направленный ациклический граф (DAWG).
Исходные данные для словаря теперь берутся из <a href="http://opencorpora.org/dict.php">opencorpora</a>.
Собственно от морфологии там только запакованный словарь, тривиальная вебморда для тестирования, парсер + код для упаковки в dawg ну и наверное все.
Поиск по словарю с выводом форм слов работает нормально, но нужно добавить предсказатель для тех слов что отсутствуют в словаре.
API пока отсутствует как класс, немного позже добавлю все эти штуки.
Вдобавок есть мысль прикрутить прослойку в виде сетевого сервиса с протоколом по типу memcache.</p>

<p>Бинарь словаря пока не прилагаю, 15 мегабайт с репы дергать постоянно не камильфо.
Если у кого есть желание поиграться отпишите в коментах, либо соберите сами</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>wget http://opencorpora.org/files/export/dict/dict.opcorpora.txt.bz2
</span><span class='line'>unpack dict.opcorpora.txt.bz2 
</span><span class='line'>ghc -hide-package vector-binary-instances -O2 BuildDict.hs -o builder
</span><span class='line'>./builder</span></code></pre></td></tr></table></div></figure>


<p>Минут за 15 - 20 и 2 гигабайта памяти с копейками, сие диво дивное родит несколько бинарных файлов,
оставить dawg.dict, в нем словарь, остальное можно удалять.
Далее скомпилировать Main.hs и запускать с той-же папки.
Доступно на локалхосте по 8000 порту.</p>

<p>Как то так.
И да если ктонить ткнет носом как оптимизировать Builder.hs чтоб он кушал меньше памяти буду сильно признателен.
Хотя памяти у меня достаточно + есть еще толстая свободная подушка, но неприятно.</p>

<p>Когда в очередной раз мне надоест пилить радио streaming сервер, доделаю морфологию до нормального состояния.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Морфология]]></title>
    <link href="http://chemist.github.com/blog/2013/03/03/morfologhiia/"/>
    <updated>2013-03-03T16:27:00+04:00</updated>
    <id>http://chemist.github.com/blog/2013/03/03/morfologhiia</id>
    <content type="html"><![CDATA[<h2>Предыстория</h2>

<p>Год назад, для одного из проектов мне понадобилась морфология, google и yandex вариантов для haskell не нашли.
Немного изучив предметную область, написал свой упрощенный вариант морфологии.</p>

<!-- more -->


<h2>Описание</h2>

<p>Словарь взял из  <a href="http://pythonhosted.org/pymorphy/">pymorphy</a>, из функционала присутствует только нормализация, все остальное мне было не нужно.</p>

<p>Пример использования:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="kr">module</span> <span class="nn">Main</span> <span class="kr">where</span>
</span><span class='line'>
</span><span class='line'><span class="kr">import</span> <span class="nn">Text.Morphology.Russian</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Data.Text</span> <span class="p">(</span><span class="nf">pack</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c1">-- | import modules for show cyrillic in console</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Data.ByteString.Char8</span> <span class="p">(</span><span class="nf">putStrLn</span><span class="p">)</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Data.Text.Encoding</span> <span class="p">(</span><span class="nf">encodeUtf8</span><span class="p">)</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Prelude</span> <span class="k">hiding</span> <span class="p">(</span><span class="nf">putStrLn</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="nf">main</span><span class="ow">::</span><span class="kt">IO</span> <span class="nb">()</span>
</span><span class='line'><span class="nf">main</span> <span class="ow">=</span> <span class="kr">do</span>
</span><span class='line'>
</span><span class='line'><span class="c1">-- | recreate binary file with morphology base, if you realy need this</span>
</span><span class='line'><span class="c1">-- |  makeMorph</span>
</span><span class='line'><span class="c1">-- | create morph.bin file in in data_dir </span>
</span><span class='line'><span class="c1">-- | about data_dir see here  [about data_dir](http://neilmitchell.blogspot.ru/2008/02/adding-data-files-using-cabal.html)</span>
</span><span class='line'>
</span><span class='line'><span class="c1">-- | load binary file from data_dir, and return IO Morph</span>
</span><span class='line'>  <span class="n">normal</span> <span class="ow">&lt;-</span> <span class="n">normalForm</span>
</span><span class='line'>
</span><span class='line'>  <span class="kr">let</span> <span class="n">check</span> <span class="ow">=</span> <span class="n">normal</span> <span class="p">(</span><span class="n">pack</span> <span class="s">&quot;есть&quot;</span><span class="p">)</span>
</span><span class='line'>  <span class="n">mapM_</span> <span class="n">putStrLn</span> <span class="o">$</span> <span class="n">map</span> <span class="n">encodeUtf8</span> <span class="n">check</span>
</span><span class='line'>  <span class="kr">let</span> <span class="n">check</span> <span class="ow">=</span> <span class="n">normal</span> <span class="p">(</span><span class="n">pack</span> <span class="s">&quot;ржи&quot;</span><span class="p">)</span>
</span><span class='line'>  <span class="n">mapM_</span> <span class="n">putStrLn</span> <span class="o">$</span> <span class="n">map</span> <span class="n">encodeUtf8</span> <span class="n">check</span>
</span></code></pre></td></tr></table></div></figure>


<p>В результате:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="o">&gt;</span> <span class="kt">:</span><span class="n">l</span> <span class="kt">Main</span>
</span><span class='line'><span class="o">&gt;</span> <span class="n">main</span>
</span><span class='line'><span class="err">быть</span>
</span><span class='line'><span class="err">есть</span>
</span><span class='line'><span class="err">есть</span>
</span><span class='line'><span class="err">рожь</span>
</span><span class='line'><span class="err">ржа</span>
</span><span class='line'><span class="err">ржать</span>
</span></code></pre></td></tr></table></div></figure>


<p>Если нормальной формы не найденно возвращается пустой список.</p>

<p>Результат по ссылке <a href="http://github.com/chemist/russian-morphology">russian-morphology</a></p>

<p>Установка как для любого cabal пакета.</p>

<h2>Мысли вслух:</h2>

<p>По хорошему нужно переписать используя <a href="http://en.wikipedia.org/wiki/Directed_acyclic_word_graph">DAWG</a>, в качестве хранилища для лемм и прочего + реализовать полный функционал.</p>
]]></content>
  </entry>
  
</feed>
