Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

2012-06-01

  • Loading branch information...
commit 15ad58f2b86e7fdf681ad50e3e39369a30783e28 1 parent 54c8169
@qnikst authored
View
60 atom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title>A simple blog</title>
+ <link href="http://example.com/atom.xml" rel="self" />
+ <link href="http://example.com" />
+ <id>http://example.com/atom.xml</id>
+ <author>
+ <name>Jasper Van der Jeugt</name>
+ </author>
+ <updated>2012-04-05T00:00:00Z</updated>
+ <entry>
+ <title>A first post</title>
+ <link href="http://example.com/posts/2012-04-05-a-first-post.html" />
+ <id>http://example.com/posts/2012-04-05-a-first-post.html</id>
+ <published>2012-04-05T00:00:00Z</published>
+ <updated>2012-04-05T00:00:00Z</updated>
+ <summary type="html"><![CDATA[$description$]]></summary>
+</entry>
+<entry>
+ <title>Запуск проекта numeric-ode</title>
+ <link href="http://example.com/posts/2012-04-06-numeric-ode-start.html" />
+ <id>http://example.com/posts/2012-04-06-numeric-ode-start.html</id>
+ <published>2012-04-06T00:00:00Z</published>
+ <updated>2012-04-06T00:00:00Z</updated>
+ <summary type="html"><![CDATA[$description$]]></summary>
+</entry>
+<entry>
+ <title>Прогресс в numeric-ode</title>
+ <link href="http://example.com/posts/2012-04-17-numeric-ode-1.html" />
+ <id>http://example.com/posts/2012-04-17-numeric-ode-1.html</id>
+ <published>2012-04-17T00:00:00Z</published>
+ <updated>2012-04-17T00:00:00Z</updated>
+ <summary type="html"><![CDATA[$description$]]></summary>
+</entry>
+<entry>
+ <title>cabal-dev</title>
+ <link href="http://example.com/posts/2012-04-30-cabal_dev.html" />
+ <id>http://example.com/posts/2012-04-30-cabal_dev.html</id>
+ <published>2012-04-30T00:00:00Z</published>
+ <updated>2012-04-30T00:00:00Z</updated>
+ <summary type="html"><![CDATA[$description$]]></summary>
+</entry>
+<entry>
+ <title>Making nixos from gentoo</title>
+ <link href="http://example.com/posts/2012-05-07-nixos.html" />
+ <id>http://example.com/posts/2012-05-07-nixos.html</id>
+ <published>2012-05-07T00:00:00Z</published>
+ <updated>2012-05-07T00:00:00Z</updated>
+ <summary type="html"><![CDATA[$description$]]></summary>
+</entry>
+<entry>
+ <title>Создание сайта на Yesod/Haskell</title>
+ <link href="http://example.com/posts/2012-05-29-creating-yesod-site.html" />
+ <id>http://example.com/posts/2012-05-29-creating-yesod-site.html</id>
+ <published>2012-05-29T00:00:00Z</published>
+ <updated>2012-05-29T00:00:00Z</updated>
+ <summary type="html"><![CDATA[$description$]]></summary>
+</entry>
+
+</feed>
View
63 contact.html
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - Contacts</title>
+ <link rel="stylesheet" type="text/css" href="./css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - Contacts
+
+ <div id="navigation">
+ <a href="./index.html">Home</a>
+ <a href="./posts.html">All posts</a>
+ <a href="./projects.html">Projects</a>
+ <a href="./contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1 id="contacts">Contacts</h1>
+<table>
+<col width="10%"></col>
+<col width="32%"></col>
+<tbody>
+<tr class="odd">
+<td align="left">JID:</td>
+<td align="left"><script type="text/javascript">
+<!--
+h='&#x67;&#x6d;&#x61;&#x69;&#108;&#46;&#x63;&#x6f;&#x6d;';a='&#64;';n='&#x71;&#110;&#x69;&#x6b;&#x73;&#116;';e=n+a+h;
+document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'">'+'<code>'+e+'</code>'+'<\/'+'a'+'>');
+// -->
+</script><noscript>qnikst at gmail dot com</noscript></td>
+</tr>
+<tr class="even">
+<td align="left">IRC:</td>
+<td align="left"><script type="text/javascript">
+<!--
+h='&#x69;&#114;&#x63;&#46;&#102;&#114;&#x65;&#x65;&#110;&#x6f;&#100;&#x65;&#46;&#110;&#x65;&#116;';a='&#64;';n='&#x71;&#110;&#x69;&#x6b;&#x73;&#116;';e=n+a+h;
+document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'">'+'<code>'+e+'</code>'+'<\/'+'a'+'>');
+// -->
+</script><noscript>qnikst at irc dot freenode dot net</noscript></td>
+</tr>
+</tbody>
+</table>
+<h2 id="about-myself">About myself</h2>
+<p>Haskell developer, physysist</p>
+<p>Here can be some info that nobody will need</p>
+<h2 id="me-on">Me on</h2>
+<ul>
+<li><a href="http://github.com/qnikst">github</a></li>
+<li><a href="http://www.linux.org.ru/people/qnikst/profile">lor</a></li>
+<li><a href="http://juick.com/qnikst/">juick</a></li>
+<li><a href="http://myanimelist.net/animelist/qnikst">myanimelist</a></li>
+</ul>
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
View
1  css/screen.css
@@ -0,0 +1 @@
+html{font-family:'Helvetica', sans-serif;font-size:14px;color:black}body{width:800px;margin:10px auto 10px auto}div#header{font-size:16px;font-weight:bold}div#navigation{float:right}div#navigation a{margin-left:10px}div#footer{text-align:center;font-style:italic;font-size:11px;margin-top:30px}h1, h2, h3, h4, h5{color:rgb(150, 150, 150);border-bottom:2px solid rgb(150, 150, 150)}h1{font-size:22px;margin-top:30px}h2{font-size:18px}li{list-style-type:square}a{color:rgb(30, 30, 130);font-weight:bold;text-decoration:none}div.figure{text-align:center}div.figure p.caption{font-style:italic}
View
BIN  images/2012-03-06/1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/2012-03-06/1e.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/2012-03-06/2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/2012-03-06/2e.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/2012-03-06/3.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/2012-03-06/3e.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/2012-03-06/4.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/2012-03-06/all.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/haskell-logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
46 index.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - Home</title>
+ <link rel="stylesheet" type="text/css" href="./css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - Home
+
+ <div id="navigation">
+ <a href="./index.html">Home</a>
+ <a href="./posts.html">All posts</a>
+ <a href="./projects.html">Projects</a>
+ <a href="./contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1 id="recent-posts">Recent posts</h1>
+<ul>
+ <li>
+
+<a href="./posts/2012-05-29-creating-yesod-site.html">Создание сайта на Yesod/Haskell</a> - <em>2012-05-29</em> - by <em>qnikst</em>
+</li>
+<li>
+
+<a href="./posts/2012-05-07-nixos.html">Making nixos from gentoo</a> - <em><span class="math"><em>d</em><em>a</em><em>t</em><em>e</em></span></em> - by <em><span class="math"><em>a</em><em>u</em><em>t</em><em>h</em><em>o</em><em>r</em></span></em>
+</li>
+<li>
+
+<a href="./posts/2012-04-30-cabal_dev.html">cabal-dev</a> - <em>2012-01-30</em> - by <em>qnikst</em>
+</li>
+
+</ul>
+
+<p><a href="./posts.html">All posts…</a></p>
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
View
37 posts.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - Archive</title>
+ <link rel="stylesheet" type="text/css" href="./css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - Archive
+
+ <div id="navigation">
+ <a href="./index.html">Home</a>
+ <a href="./posts.html">All posts</a>
+ <a href="./projects.html">Projects</a>
+ <a href="./contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1 id="all-posts">All posts</h1>
+<ul>
+<li><a href="./posts/2012-05-29-creating-yesod-site.html">Создание сайта на Yesod/Haskell</a> - <em>2012-05-29</em> - by <em>qnikst</em></li>
+<li><a href="./posts/2012-05-07-nixos.html">Making nixos from gentoo</a> - <em>$date$</em> - by <em>$author$</em></li>
+<li><a href="./posts/2012-04-30-cabal_dev.html">cabal-dev</a> - <em>2012-01-30</em> - by <em>qnikst</em></li>
+<li><a href="./posts/2012-04-17-numeric-ode-1.html">Прогресс в numeric-ode</a> - <em>2012-01-04</em> - by <em>qnikst</em></li>
+<li><a href="./posts/2012-04-06-numeric-ode-start.html">Запуск проекта numeric-ode</a> - <em>2012-01-05</em> - by <em>qnikst</em></li>
+<li><a href="./posts/2012-04-05-a-first-post.html">A first post</a> - <em>2012-01-04</em> - by <em>qnikst</em></li>
+</ul>
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
View
52 posts/2012-04-05-a-first-post.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - A first post</title>
+ <link rel="stylesheet" type="text/css" href="../css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - A first post
+
+ <div id="navigation">
+ <a href="../index.html">Home</a>
+ <a href="../posts.html">All posts</a>
+ <a href="../projects.html">Projects</a>
+ <a href="../contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1>A first post</h1>
+
+<p>by <em>qnikst</em> on <strong>2012-01-04</strong></p>
+
+<p>Some post to start blog, this will be rewriten soon</p>
+
+<div id="disqus_thread"></div>
+
+<script type="text/javascript">
+//
+/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+var disqus_shortname = 'qnikst'; // required: replace example with your forum shortname
+
+/* * * DON'T EDIT BELOW THIS LINE * * */
+(function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+})();
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+//
+</script>
+
+
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
View
232 posts/2012-04-06-numeric-ode-start.html
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - Запуск проекта numeric-ode</title>
+ <link rel="stylesheet" type="text/css" href="../css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - Запуск проекта numeric-ode
+
+ <div id="navigation">
+ <a href="../index.html">Home</a>
+ <a href="../posts.html">All posts</a>
+ <a href="../projects.html">Projects</a>
+ <a href="../contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1>Запуск проекта numeric-ode</h1>
+
+<p>by <em>qnikst</em> on <strong>2012-01-05</strong></p>
+
+<p>Наконец-то нашёл в себе силы и немного времени начать новый проект на haskell. Решалку ODE, в принципе этих решалок и так дофига, но мне оказались нужны определенные хитрые алгоритмы многие их, которых строятся на функциях высшего порядка, и писать их на c/fortran/matlab было бы достаточно грустно, а известные реализации с трудом прикладываются к моим задачам. В общем надеюсь, что-то путное выйдет. Если кому интересно и кто видит явные косяки буду рад любым замечаниям.</p>
+<p>Страница проекта: <a href="https://github.com/qnikst/numeric-ode">odessolver</a></p>
+<p>Немного о том, как всё будет работать все методы работают на основе интегратора (функции для каждой системы, которая по шагу и начальной координате возвращает следующую). В целом видно, что существуют и более сложные варианты, напр. возвращение следующей координаты и нового интегратора, но это уже потом.</p>
+<p>Ну и для разминки привожу, пример, простейших учебных методов (Examples/LottkaVolterra.hs), собственно весь этот пост является .lhs файлом и может быть запущен, похоже, что в решении есть косяк, но пока я ещё не разобрался с тем проблема в исходном коде или в коде какой либо из используемых библиотек.</p>
+<pre><code>&gt; {-# LANGUAGE FlexibleInstances, BangPatterns, TypeFamilies #-}
+&gt; module Examples.LottkaVollterra
+&gt; where
+
+First we import some stuff that we will use for compulations.
+All computations will run it ST monad and we will use Vector
+to store results, it not the most effective way to do it in
+haskell but it is quite common in numerical engines (like Octave,
+Matlab, etc.)
+For generazation of algorithms on arbitrary space we'll use
+VectorSpace.
+
+&gt; import Prelude hiding (sequence)
+&gt; import Control.Monad.ST
+&gt; import Control.Monad
+&gt; import Data.Vector (Vector,(!))
+&gt; import qualified Data.Vector as V
+&gt; import Data.AdditiveGroup
+&gt; import Data.VectorSpace
+
+Then we import some stuff for plotting graphs
+
+&gt; import Data.Accessor
+&gt; import Graphics.Rendering.Chart
+&gt; import Data.Colour.Names
+&gt; import Data.Colour
+
+And now our main part
+
+
+&gt; import Math.Integrators
+&gt; import Math.Integrators.ExplicitEuler
+&gt; import Math.Integrators.ImplicitEuler
+&gt; import Math.Integrators.ImplicitMidpointRule
+&gt; import Math.Integrators.SympleticEuler
+
+
+First model will be Lotka-Volterra model, that was used to
+estimate predators-prey number
+
+[1] http://en.wikipedia.org/wiki/Lotka%E2%80%93Volterra_equation
+\begin{equation}
+ \left\{
+ \begin{array}{ccc}
+ \dot{u} &amp; = &amp; u (v - 2) \\
+ \dot{v} &amp; = &amp; v (1 - u)
+ \end{array}
+ \right.
+\end{equation}
+
+To store our $R^2$ space we'll use special data type, that is
+strict and has fixed size
+
+&gt; data T2 = T2 !Double !Double
+&gt; deriving (Eq,Show)
+
+To be able to use it we need to make it instance of vector space:
+
+&gt; instance AdditiveGroup T2 where
+&gt; zeroV = T2 0 0
+&gt; negateV (T2 x y) = T2 (-x) (-y)
+&gt; (T2 a1 a2) ^+^ (T2 b1 b2) = T2 (a1+b1) (a2+b2)
+
+&gt; instance VectorSpace T2 where
+&gt; type Scalar T2 = Double
+&gt; c *^ (T2 a1 a2) = T2 (c*a1) (c*a2)
+
+
+Now let's define our equation:
+
+&gt; lv :: T2 -&gt; T2
+&gt; lv (T2 u v) = T2 (u * (v-2)) (v * (1-u))
+
+Create initial condition list (maybe I'll use it)
+
+&gt; ics = [ T2 2 2, T2 4 8, T2 4 2,T2 6 2]
+
+Create initial conditions for testing purposes
+
+&gt; ic = T2 2 2
+
+That LV equation has next first integral that should be preserved:
+
+&gt; realline :: T2 -&gt; Double
+&gt; realline (T2 u v) = (log u) - u + 2*(log v) -v
+
+Define a function that find difference in first integrals (i.e. error)
+
+&gt; errorV ic v = V.map (\x -&gt; abs $! (realline x) - (realline ic)) v
+
+We'll use solve equation from 0 to 100 with 0.12 step
+
+&gt; tm = V.enumFromStepN 0 0.12 100
+
+Our solvers:
+
+&gt; solve1 ic tm = runST $ integrateV (explicitEuler lv) ic tm
+&gt; solve2 ic tm = runST $ integrateV (implicitEuler lv norm) ic tm
+&gt; solve3 ic tm = runST $ integrateV (imr lv norm) ic tm
+
+some results:
+
+&gt; result1 = solve1 ic tm
+&gt; result2 = solve2 ic tm
+&gt; result3 = solve3 ic tm
+
+to use sympletic method we should redefine out equation
+in this place I really need an advice how to do it implictly in terms
+of First Order functions
+
+&gt; splitIc :: T2 -&gt; (Double,Double)
+&gt; splitIc (T2 u v) = (u,v)
+
+&gt; splitLv :: ((Double -&gt; Double -&gt; Double),(Double-&gt;Double-&gt;Double))
+&gt; splitLv = (\u v -&gt; u*(v-2), \u v -&gt; v*(1-u))
+
+&gt; solve4 ic tm = runST $ integrateV (sympleticEuler1 splitLv abs) (splitIc ic) tm
+&gt; result4 = solve4 ic tm
+
+Some helpers: norm on T2 space
+
+&gt; norm :: T2 -&gt; Double
+&gt; norm (T2 a b) = a*a+b*b
+
+Now lets create charts:
+ first: plot all graphs on the same plot:
+
+&gt; plot1 = renderableToPNGFile (mychart) 640 480 &quot;all.png&quot;
+&gt; where
+&gt; mychart = chart &quot;All methods&quot; lst
+&gt; lst = [(&quot;Explicit Euler&quot;, blue, f solve1)
+&gt; ,(&quot;Implicit Euler&quot;, green, f solve2)
+&gt; ,(&quot;Implicit Midpoint Rule&quot;, red, f solve3)
+&gt; ,(&quot;Sympletic Euler&quot;, magenta, f' solve4)]
+&gt; f g = v2d $! g ic tm
+&gt; f' g = V.toList $! g ic tm
+&gt; plotI fn nm f ics = renderableToPNGFile (mychart) 640 480 fn
+&gt; where
+&gt; mychart = chart nm lst
+&gt; lst = zipWith3 (\x y z -&gt; (x,y,z)) (map show ics) [blue,green,red,magenta,orange] (map f ics)
+&gt; plotE fn nm f ics = renderableToPNGFile (mychart) 640 480 fn
+&gt; where
+&gt; mychart = chart nm lst
+&gt; lst = zipWith3 (\x y z -&gt; (x,y,z)) (map show ics) [blue,green,red,magenta,orange]
+&gt; (map (\i -&gt; zipWith (,) (V.toList tm) (V.toList $! errorV i $! f i)) ics)
+&gt; plot2 = plotI &quot;1.png&quot; &quot;Explicit Euler&quot; (v2d . (flip solve1 tm)) ics
+&gt; plot3 = plotI &quot;2.png&quot; &quot;Implicit Euler&quot; (v2d . (flip solve2 tm)) ics
+&gt; plot4 = plotI &quot;3.png&quot; &quot;IMR&quot; (v2d . (flip solve3 tm)) ics
+&gt; plot5 = plotI &quot;4.png&quot; &quot;Sypletic&quot; (V.toList . (flip solve4 tm)) ics
+&gt; plot6 = plotE &quot;1e.png&quot; &quot;Explicit Euler Error&quot; (flip solve1 tm) ics
+&gt; plot7 = plotE &quot;2e.png&quot; &quot;Implicit Euler Error&quot; (flip solve2 tm) ics
+&gt; plot8 = plotE &quot;3e.png&quot; &quot;IMR Error&quot; (flip solve3 tm) ics
+&gt; --plot7 = plotE &quot;2e.png&quot; &quot;Implicit Euler Error&quot; (flip solve2 tm) ics
+
+&gt; chart tit lst = toRenderable layout
+&gt; where
+&gt; plotList = map (Left . toPlot . mtp) lst
+&gt; mtp (tit,clr,dt) = plot_lines_style .&gt; line_color ^= opaque clr
+&gt; $ plot_lines_title ^= tit
+&gt; $ plot_lines_values ^= [dt]
+&gt; $ defaultPlotLines
+&gt; layout = layout1_plots ^= plotList
+&gt; $ layout1_title ^= tit
+&gt; $ defaultLayout1
+&gt; v2d = (map (\(T2 x y) -&gt; (x,y))) . V.toList
+
+&gt; main = plot1 &gt;&gt; plot2 &gt;&gt; plot3 &gt;&gt; plot4 &gt;&gt; plot5 &gt;&gt; plot6 &gt;&gt; plot7 &gt;&gt; plot8</code></pre>
+<p>а для осиливших немножно незжатых картинок:</p>
+<img src="../images/2012-03-06/all.png" alt="image"></img>
+<img src="../images/2012-03-06/1.png" alt="image"></img>
+<img src="../images/2012-03-06/1e.png" alt="image"></img>
+<img src="../images/2012-03-06/2.png" alt="image"></img>
+<img src="../images/2012-03-06/2e.png" alt="image"></img>
+<img src="../images/2012-03-06/3.png" alt="image"></img>
+<img src="../images/2012-03-06/3e.png" alt="image"></img>
+<img src="../images/2012-03-06/4.png" alt="image"></img>
+<img src="../images/2012-03-06/4e.png" alt="image"></img>
+
+<div id="disqus_thread"></div>
+
+<script type="text/javascript">
+//
+/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+var disqus_shortname = 'qnikst'; // required: replace example with your forum shortname
+
+/* * * DON'T EDIT BELOW THIS LINE * * */
+(function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+})();
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+//
+</script>
+
+
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
View
55 posts/2012-04-17-numeric-ode-1.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - Прогресс в numeric-ode</title>
+ <link rel="stylesheet" type="text/css" href="../css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - Прогресс в numeric-ode
+
+ <div id="navigation">
+ <a href="../index.html">Home</a>
+ <a href="../posts.html">All posts</a>
+ <a href="../projects.html">Projects</a>
+ <a href="../contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1>Прогресс в numeric-ode</h1>
+
+<p>by <em>qnikst</em> on <strong>2012-01-04</strong></p>
+
+<p>В numeric-ode был добавлен метод Störmer-Verlet. Для решения уравнений</p>
+<blockquote>
+<p>y’’ = f(y)</p>
+</blockquote>
+
+<div id="disqus_thread"></div>
+
+<script type="text/javascript">
+//
+/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+var disqus_shortname = 'qnikst'; // required: replace example with your forum shortname
+
+/* * * DON'T EDIT BELOW THIS LINE * * */
+(function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+})();
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+//
+</script>
+
+
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
View
80 posts/2012-04-30-cabal_dev.html
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - cabal-dev</title>
+ <link rel="stylesheet" type="text/css" href="../css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - cabal-dev
+
+ <div id="navigation">
+ <a href="../index.html">Home</a>
+ <a href="../posts.html">All posts</a>
+ <a href="../projects.html">Projects</a>
+ <a href="../contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1>cabal-dev</h1>
+
+<p>by <em>qnikst</em> on <strong>2012-01-30</strong></p>
+
+<blockquote>
+<p>Q: how to use cabal?</p>
+<p>A: just cabal install cabal-dev</p>
+</blockquote>
+<p>Cabal is a great system of building and packaging Haskell libraries but is has some downsides such as:</p>
+<blockquote>
+<p>1 it has very poor handling of library versions and tracking dependecies.</p>
+<p>2 it can’t have multiply versions of same library (really it can but then it becomes a pain to use them)</p>
+</blockquote>
+<p>So sometimes it becomes a pain to fix haskell tree.</p>
+<p>Cabal-dev is a cabal-install wrapper that build project and dependencies in sandboxed enviromnent, this allowes to use multiple version of the same library and so chanses to break system are very low. Additionally it generates image of installed application so you can check how it will be installed on your system without real installation.</p>
+<p>Of cause as there are some problems:</p>
+<blockquote>
+<p>1 cabal-dev is <em>slow</em>, because you should install all dependencies in sandbox environment (unless they are installed system wide).</p>
+<p>2 cabal-dev can’t handle some Setup.hs options at least it was true in Dec-2011.</p>
+</blockquote>
+<p>First problem easily fixed in gentoo, one can install basic dependencies with emerge, so portage will track tree consitency with `haskell-updater &lt;<a href="http://www.haskell.org/haskellwiki/Gentoo#haskell-updater">http://www.haskell.org/haskellwiki/Gentoo#haskell-updater</a>&gt;` (replacement tool for ghc-updater) and has all other features out of the box. So cabal-dev will be using most of libs from system and some other will be sandboxed.</p>
+<p>For second one I had a workaround by creating makefile that run setup.hs and then <code>cabal-dev intall</code>.</p>
+<p>Also cabal-dev has additional feature of running built program in ghc (i.e. run ghci and load every module in project) it can be done with</p>
+<blockquote>
+<p>cabal-dev build &amp;&amp; cabal-dev ghci</p>
+</blockquote>
+<p>Usefull links:</p>
+<blockquote>
+<ul>
+<li><a href="https://github.com/creswick/cabal-dev">docs</a></li>
+<li><a href="http://hackage.haskell.org/package/cabal-dev">hackage</a></li>
+</ul>
+</blockquote>
+
+<div id="disqus_thread"></div>
+
+<script type="text/javascript">
+//
+/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+var disqus_shortname = 'qnikst'; // required: replace example with your forum shortname
+
+/* * * DON'T EDIT BELOW THIS LINE * * */
+(function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+})();
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+//
+</script>
+
+
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
View
67 posts/2012-05-07-nixos.html
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - Making nixos from gentoo</title>
+ <link rel="stylesheet" type="text/css" href="../css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - Making nixos from gentoo
+
+ <div id="navigation">
+ <a href="../index.html">Home</a>
+ <a href="../posts.html">All posts</a>
+ <a href="../projects.html">Projects</a>
+ <a href="../contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1>Making nixos from gentoo</h1>
+
+<p>by <em>$author$</em> on <strong>$date$</strong></p>
+
+<h1 id="make-new-gentoo-chroot">1. make new gentoo chroot</h1>
+<blockquote>
+<ol style="list-style-type: decimal">
+<li>run `gentoo-chrootiez[http://hackie.blog.tut.by/2012/03/08/gentoo-chrootiez-in-30-seconds/]`_</li>
+<li>I add `haskell-overlay[http://]`_ to the list off overlays</li>
+</ol>
+<dl>
+<dt>3. run:</dt>
+<dd><p>emerge -av nix</p>
+</dd>
+</dl>
+<ol start="4" style="list-style-type: decimal">
+<li>follow <a href="http://hydra.nixos.org/build/2517746/download/1/manual">http://hydra.nixos.org/build/2517746/download/1/manual</a>/ instructions</li>
+</ol>
+</blockquote>
+<p>Congratulations you’ve done!</p>
+
+<div id="disqus_thread"></div>
+
+<script type="text/javascript">
+//
+/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+var disqus_shortname = 'qnikst'; // required: replace example with your forum shortname
+
+/* * * DON'T EDIT BELOW THIS LINE * * */
+(function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+})();
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+//
+</script>
+
+
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
View
347 posts/2012-05-29-creating-yesod-site.html
@@ -0,0 +1,347 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - Создание сайта на Yesod/Haskell</title>
+ <link rel="stylesheet" type="text/css" href="../css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - Создание сайта на Yesod/Haskell
+
+ <div id="navigation">
+ <a href="../index.html">Home</a>
+ <a href="../posts.html">All posts</a>
+ <a href="../projects.html">Projects</a>
+ <a href="../contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1>Создание сайта на Yesod/Haskell</h1>
+
+<p>by <em>qnikst</em> on <strong>2012-05-29</strong></p>
+
+<p>В данном посте описывается создание очень простого сайта на haskell движке <a href="http://www.yesodweb.com">yesod</a> на примере цитатника форума и канала gentoo.ru.</p>
+<h2 id="подготовка-к-соданию">Подготовка к соданию</h2>
+<p>Для создания сайта необходим сам фреймвок <code>yesod</code>, который может быть установлен с помощью утилиты <code>cabal</code>. В случае если Вы являетесь счасливым обладателем дистрибутива gentoo, то можно установить yesod из <a href="http://www.haskell.org/haskellwiki/Gentoo#Gentoo_Haskell_Overlay">haskell-overlay</a>.</p>
+<pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># layman -a haskell</span>
+<span class="co"># emerge -av yesod</span></code></pre>
+<p>Заголовка сайта создаётся с помощью простой утилиты <code>yesod</code>:</p>
+<pre class="sourceCode bash"><code class="sourceCode bash">qnikst@qwork ~/workspace/myself $ yesod init
+Welcome to the Yesod scaffolder.
+...</code></pre>
+<p>Будет задано несколько вопросов о названии проета, авторе, лицензии и типе используемого движка базы данных. На основе этой информации будет создана заготовка</p>
+<p>Результатом будет созданный шаблон сайта:</p>
+<pre><code> \
+ |- Application.hs -- модуль приложения
+ |- devel.hs -- вспомогательный файл для запуска приложеия в режиме отладки
+ |- deploy -- каталог для деплоймента с помощью heroku
+ |- Foundation.hs -- Основной файл проекта, где задаются типы данных приложения
+ |- Import.hs -- Вспомогательный файл, для того, чтобы не упростить импорт
+ | функций в другие файлы
+ |- main.hs -- вспомогательны файл для запуска приложения в нормальном
+ | режиме
+ |- messages -- файлы переводов I18n
+ |- Model.hs -- файл где будут создавать модели БД
+ |- Model -- каталог для хранения доп моделей (не автосгенерированных
+ | и дополнительных функций
+ |- Settings.hs -- файл настроек (и обработки настроек сайта)
+ |- Settings -- доп. настройки
+ |- test -- каталог с тестами системы
+ |- templates -- каталог шаблонов
+ |- ygruq.cabal -- кабал файл описывающий сборку
+ |- config -- конфигурационные файлы
+ |- models -- файл моделей
+ |- routes -- файл путе
+ |- setting.yml -- yaml файл насторек проекта
+ |- sqlite.yml -- настройки БД</code></pre>
+<p>Естественно для маленького проекта это очень сильное переусложнение структуры и можно сделать гораздо более простое yesod приложение состоящее из одного файла, но поскольку хочется разобраться в том, как проект должен выглядеть в сложном варианте, то мы рассматриваем всю структуру.</p>
+<p>Далее (если используется gentoo) удалим лишние зависимости в cabal файле это yesod-platform, которая лишь для того, чтобы спасать от dependency-hell, но поскольку в gentoo он уже решён, то этой проблемы нет. Так же я временно убрал зависимость от yesod-test поскольку в этом проекте тесты пока не используются.</p>
+<h1 id="настраиваем-пути">Настраиваем пути</h1>
+<p>Официальный мануал: <a href="http://www.yesodweb.com/book/routing-and-handlers">http://www.yesodweb.com/book/routing-and-handlers</a></p>
+<p>Следующем шагом будет создание путей. Yesod позиционируется как REST фреймворк поэтому он спроектирован для использования соотвествующей раскладки, но для чистого html сайта это не очень удобно, поэтому мы сделаем более простою структуру: модель-действие-параметры</p>
+<p>Для того, чтобы определиться со структурой выделим основной фунционал сайта:</p>
+<pre><code>1. создание цитаты
+2. вывод списка цитат
+3. вывод конкретной цитаты
+4. вывод бездны
+5. вывод rss</code></pre>
+<p>И отобразим этот фукционал на структуру сайта</p>
+<pre><code>/quote/create QuoteCreateR GET POST
+/quote/list QuoteListR GET
+/quote/show/#QuoteId QuoteShowR GET
+/quote/list/#Int QuoteListPageR GET
+/quote/abyss/ QuoteAbyssListR GET
+/quote/abyss/process QuoteAbyssProcessR POST
+/quote/rss QuoteFeedR GET</code></pre>
+<p>Для каждого пути нужно создать свой метод вида <code>httpMethod</code>TypeName. В путях можно использовать стандартные типы haskell и свои типы если в пути используется такая переменная, то тако аргумент должен быть и у функции обработчика (см. ниже)</p>
+<p>Каждый из типов можно использовать для автоматического создания безопасных url, так вызов QuoteCreateR или QuoteListPageR 3 выдаст ссылки на содание цитаты и 3-ю страницу соотвественно.</p>
+<p>Далее создадим обработчик Handler/Quote.hs и добавим туда заглушки для методов:</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">{-# LANGUAGE ScopedTypeVariables, OverloadedStrings #-}</span>
+<span class="kw">module</span> <span class="dt">Handler.Quote</span>
+ <span class="kw">where</span>
+
+<span class="kw">import</span> <span class="dt">Import</span>
+
+<span class="ot">postQuoteCreateR ::</span> <span class="dt">Handler</span> <span class="dt">RepHtml</span>
+postQuoteCreateR <span class="fu">=</span> <span class="fu">undefined</span>
+
+<span class="ot">getQuoteCreateR ::</span> <span class="dt">Handler</span> <span class="dt">RepHtml</span>
+getQuoteCreateR <span class="fu">=</span> <span class="fu">undefined</span>
+
+<span class="ot">getQuoteListPageR::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Handler</span> <span class="dt">RepHtml</span>
+getQuoteListPageR page <span class="fu">=</span> <span class="fu">undefined</span></code></pre>
+<p>Теперь в файл Application.hs добавим импорт созданного обработчика Handler.Quote:</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">import</span> <span class="dt">Handler.Quote</span></code></pre>
+<h2 id="создание-моделей">Создание моделей</h2>
+<p>Официальная документация: <a href="http://www.yesodweb.com/book/persistent">http://www.yesodweb.com/book/persistent</a></p>
+<p>Теперь в файле ‘config/model’ создаём модели для сайта. Добавляем туда модель для цитаты, с полями автор цитаты, отправитель, источник, подтверждающая ссылка, текст цитаты, время отправления цитаты, является ли цитата подтвержденной.</p>
+<pre><code> Quote
+ author Text
+ sender Text
+ source Text
+ prooflink Text
+ text Text
+ timestamp UTCTime default=now()
+ is_approved Bool default=False</code></pre>
+<p>Для того, чтобы это дело собралось необходимо в файл моделей добавить импорт модуля Data.Time в файле Model.hs и в cabal файл нужно добавить зависимость от пакета time.</p>
+<h2 id="проверка">Проверка</h2>
+<p>Теперь проект можно собирать. .. $ cabal-dev configure &amp;&amp; yesod –dev devel</p>
+<p>После сборки проект можно посмотреть по адресу http://localhost:3000/.</p>
+<h1 id="непосредственное-создание-сайта">Непосредственное создание сайта</h1>
+<h2 id="вывод-списка-цитат">Вывод списка цитат</h2>
+<p>Обработаем QuotesListR для вывода всех принятых цитат. Для этого мы должны загрузить все цитаты удовлетворяющие требованию и показать их.</p>
+<p>Поскольку цитаты нужно показывать в нескольких местах, то логично для их представления сделать шаблон (showQuote), который на вход получает цитату, которую нужно показать и возвращает виджет, которы может быть включен в вёрстку.</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="co">-- file: Handler/Quote.hs</span>
+
+showQuote quote <span class="fu">=</span> <span class="fu">$</span>(whamletFile <span class="st">&quot;templates/quote-show.hamlet&quot;</span>)
+
+<span class="ot">getQuoteListR ::</span> <span class="dt">Handler</span> <span class="dt">RepHtml</span>
+getQuoteListR <span class="fu">=</span> <span class="kw">do</span>
+ quotes <span class="ot">&lt;-</span> runDB <span class="fu">$</span> selectList [<span class="dt">QuoteApproved</span> <span class="fu">==.</span> <span class="kw">True</span>] []
+ defaultLayout <span class="fu">$</span>(widgetFile <span class="st">&quot;quote-list&quot;</span>) </code></pre>
+<p>и создадим для вывода цитаты:</p>
+<pre class="hamlet"><code>$forall Entity quoteId quote &lt;- quotes
+ &lt;input type=checkbox name=abyss value=#{show $ unKey quoteId}&gt;</code></pre>
+<p>и сам виджет цитаты:</p>
+<pre class="hamlet"><code>-- file: templates/quote-show.hamlet
+&lt;div .quote&gt;
+ &lt;pre&gt;#{unTextarea (quoteText quote)}
+ \
+ \ --
+ $maybe author &lt;- quoteAuthor quote
+ author
+ (#{quoteSource quote})
+ &lt;a href=#{quoteProoflink quote}&gt;пруфлинк
+ \ цитату прислал
+ $maybe sender &lt;- quoteSender quote
+ #{sender}
+ $nothing
+ анонимный друг
+ (#{showTime (quoteTimestamp quote)})</code></pre>
+<p>Таким же образом сделаем и бездну.</p>
+<h2 id="создание-формы-добавления">Создание формы добавления</h2>
+<p>Для добавления цитат используем встроенные в yesod формы, тут удобнее всего будет использовать ApplicativeForm. В данном случае форма представляет собой функцию, которая возвращает результирующий тип данных в случае успеха список ошибок в случае если что-то не так. Ниже приведена используемая форма. Тут aopt используется для необязательного параметра, areq для обязательного, а pure подставляет значение не создавая элемента формы.</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">quoteAForm ::</span> <span class="dt">UTCTime</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Quote</span> <span class="ot">-&gt;</span> <span class="dt">AForm</span> <span class="dt">App</span> <span class="dt">App</span> <span class="dt">Quote</span>
+quoteAForm time mquote <span class="fu">=</span> <span class="dt">Quote</span>
+ <span class="fu">&lt;$&gt;</span> aopt textField <span class="st">&quot;Автор&quot;</span> (quoteAuthor <span class="fu">&lt;$&gt;</span> mquote)
+ <span class="fu">&lt;*&gt;</span> aopt textField <span class="st">&quot;Отправитель&quot;</span> (quoteSender <span class="fu">&lt;$&gt;</span> mquote)
+ <span class="fu">&lt;*&gt;</span> areq (selectFieldList sources) <span class="st">&quot;Место&quot;</span> (quoteSource <span class="fu">&lt;$&gt;</span> mquote)
+ <span class="fu">&lt;*&gt;</span> areq urlField <span class="st">&quot;Ссылка&quot;</span> (quoteProoflink <span class="fu">&lt;$&gt;</span> mquote)
+ <span class="fu">&lt;*&gt;</span> areq textareaField <span class="st">&quot;Текст&quot;</span> (quoteText <span class="fu">&lt;$&gt;</span> mquote)
+ <span class="fu">&lt;*&gt;</span> pure time
+ <span class="fu">&lt;*&gt;</span> pure <span class="kw">False</span>
+ <span class="kw">where</span>
+<span class="ot"> sources ::</span> [(<span class="dt">Text</span>,<span class="dt">LinkSource</span>)]
+ sources <span class="fu">=</span> [(<span class="st">&quot;gentoo.ru&quot;</span>,<span class="dt">Gru</span>)
+ ,(<span class="st">&quot;gentoo@conference.gentoo.ru&quot;</span>,<span class="dt">GruConf</span>)
+ ,(<span class="st">&quot;gentoo@conference.jabber.ru&quot;</span>,<span class="dt">JRuConf</span>)
+ ,(<span class="st">&quot;gentoo-user-ru@lists.gentoo.org&quot;</span>,<span class="dt">RuMail</span>)
+ ,(<span class="st">&quot;ru.gentoo-wiki.com&quot;</span>,<span class="dt">RuWiki</span>)
+ ,(<span class="st">&quot;Другое&quot;</span>,<span class="dt">OtherSource</span>)]</code></pre>
+<p>Шаблон формы. Важно, что мы создаёт два варинта отправки формы только для просмотра и для добавления и это должно быть обработано.</p>
+<pre class="hamlet"><code>&lt;form method=post action=@{QuoteCreateR} enctype=#{enctype}&gt;
+ &lt;table&gt;
+ ^{formWidget}
+ &lt;input type=submit name=add value=Добавить&gt;
+ &lt;input type=submit name=show value=Посмотреть&gt;</code></pre>
+<p>Показ формы на странице создания:</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">getQuoteCreateR ::</span> <span class="dt">Handler</span> <span class="dt">RepHtml</span>
+getQuoteCreateR <span class="fu">=</span> <span class="kw">do</span>
+ <span class="kw">let</span> pageType <span class="fu">=</span> <span class="dt">Create</span>
+ time <span class="ot">&lt;-</span> liftIO <span class="fu">$</span> zonedTimeToUTC <span class="fu">&lt;$&gt;</span> getZonedTime
+ (formWidget,enctype) <span class="ot">&lt;-</span> generateFormPost <span class="fu">$</span> renderTable <span class="fu">$</span> quoteAForm time <span class="kw">Nothing</span>
+ defaultLayout <span class="fu">$</span> <span class="kw">do</span>
+ <span class="fu">$</span>(widgetFile <span class="st">&quot;quote-list-wrapper&quot;</span>)</code></pre>
+<p>Показ формы на другой странице</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell">quoteCreate formWidget enctype <span class="fu">=</span> <span class="fu">$</span>(widgetFile <span class="st">&quot;quote-create&quot;</span>)
+anyhanler <span class="fu">=</span> <span class="kw">do</span>
+ time <span class="ot">&lt;-</span> liftIO <span class="fu">$</span> zonedTimeToUTC <span class="fu">&lt;$&gt;</span> getZonedTime
+ (formWidget,enctype) <span class="ot">&lt;-</span> generateFormPost <span class="fu">$</span> renderTable <span class="fu">$</span> quoteAForm time <span class="kw">Nothing</span></code></pre>
+<p>Обработка формы:</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">postQuoteCreateR ::</span> <span class="dt">Handler</span> <span class="dt">RepHtml</span>
+postQuoteCreateR <span class="fu">=</span> <span class="kw">do</span>
+ time <span class="ot">&lt;-</span> liftIO <span class="fu">$</span> zonedTimeToUTC <span class="fu">&lt;$&gt;</span> getZonedTime
+ ((result,formWidget),enctype) <span class="ot">&lt;-</span> runFormPost <span class="fu">$</span> renderDivs <span class="fu">$</span> quoteAForm time <span class="kw">Nothing</span>
+ showOnly <span class="ot">&lt;-</span> lookupPostParam <span class="st">&quot;show&quot;</span> <span class="co">-- проверям нажато ли только просмотр</span>
+ <span class="kw">case</span> result <span class="kw">of</span>
+ <span class="dt">FormSuccess</span> quote <span class="ot">-&gt;</span> <span class="kw">do</span>
+ <span class="kw">if</span> isJust showOnly
+ <span class="kw">then</span> setMessage [shamlet<span class="fu">|</span>Просмотр цитаты <span class="fu">&lt;</span>strong<span class="fu">&gt;</span>цитата не добавлена&lt;<span class="fu">/</span>strong<span class="fu">&gt;|</span>]
+ <span class="kw">else</span> <span class="kw">do</span> <span class="co">-- добавляем цитату и редиректим пользователя на её просмотр</span>
+ quoteId <span class="ot">&lt;-</span> runDB (insert quote)
+ setMessage [shamlet<span class="fu">|</span>Цитата была успешно добавлена|]
+ createFile
+ toMaster <span class="ot">&lt;-</span> getRouteToMaster
+ redirect <span class="fu">$</span> toMaster <span class="fu">$</span> <span class="dt">QuoteShowR</span> quoteId
+ defaultLayout <span class="fu">$</span> <span class="kw">do</span>
+ <span class="fu">$</span>(widgetFile <span class="st">&quot;quote-show&quot;</span>)
+ <span class="fu">$</span>(widgetFile <span class="st">&quot;quote-create&quot;</span>)
+ _other <span class="ot">-&gt;</span> <span class="kw">do</span> <span class="co">-- просто показываем форму со всеми ошибками</span>
+ defaultLayout <span class="fu">$</span> <span class="kw">do</span>
+ <span class="fu">$</span>(widgetFile <span class="st">&quot;quote-create&quot;</span>)</code></pre>
+<h2 id="логин-администратора">Логин администратора</h2>
+<p>В есод встроена система авторизации на основе разных провайтеров таких как</p>
+<ul>
+<li>OpenId</li>
+<li>BrowserId</li>
+<li>Database password</li>
+</ul>
+<p>Для простоты в данном случае используется browserid. Поскольку на данном сайте все авторизованные пользователи являются администраторами, то необходимо изменить логику по умолчанию (когда новый пользователь автоматически регистрируется).</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="co">-- file: Foundation.hs</span>
+ getAuthId creds <span class="fu">=</span> runDB <span class="fu">$</span> <span class="kw">do</span>
+ x <span class="ot">&lt;-</span> getBy <span class="fu">$</span> <span class="dt">UniqueUser</span> <span class="fu">$</span> credsIdent creds
+ <span class="kw">case</span> x <span class="kw">of</span>
+ <span class="kw">Just</span> (<span class="dt">Entity</span> uid _) <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="fu">$</span> <span class="kw">Just</span> uid
+ <span class="kw">Nothing</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="kw">Nothing</span></code></pre>
+<p>Теперь в обработчиках мы можем добавить “maid &lt;- maybeAuth” для проверки является ли пользователь администратором и “requireAuth” для того, чтобы потребовать авторизацию</p>
+<p>Теперь в шаблон ‘quote-list’ добавим необходимые детали</p>
+<pre class="hamlet"><code>^{pager}
+$maybe _ &lt;- maid
+ &lt;form action=@{QuoteAbyssProcessR} method=post&gt;
+ $forall Entity quoteId quote &lt;- quotes
+ &lt;input type=checkbox name=abyss value=#{show $ unKey quoteId}&gt;
+ ^{showQuote quote}
+ &lt;div&gt;
+ &lt;input type=submit name=delete value=Удалить&gt;
+ &lt;input type=submit name=approve value=Опубликовать&gt;
+$nothing
+ \
+ $forall Entity quoteId quote &lt;- quotes
+ ^{showQuote quote}</code></pre>
+<h2 id="обработка-бездны">Обработка бездны</h2>
+<p>В шаблоне выше была вручную создана форма для принятия и удаления цитат, теперь нужно сделать обрабочик, логично, что использование автоматической формы в yesod не является хорошим решением и проще обработать данные вручную:</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">postQuoteAbyssProcessR ::</span> <span class="dt">Handler</span> <span class="dt">RepHtml</span>
+postQuoteAbyssProcessR <span class="fu">=</span> <span class="kw">do</span>
+ _ <span class="ot">&lt;-</span> requireAuth <span class="co">-- требуем авторизации</span>
+ <span class="co">-- получаем список параметров из запроса</span>
+ toDelete <span class="ot">&lt;-</span> lookupPostParam <span class="st">&quot;delete&quot;</span>
+ toApprove <span class="ot">&lt;-</span> lookupPostParam <span class="st">&quot;approve&quot;</span>
+ qLst <span class="ot">&lt;-</span> lookupPostParams <span class="st">&quot;abyss&quot;</span> <span class="co">-- тут параметром много (?abyss=1&amp;abyss=2...)</span>
+ <span class="kw">let</span> qlst' <span class="fu">=</span> <span class="fu">map</span> (<span class="dt">Key</span> <span class="fu">.</span> <span class="fu">read</span> <span class="fu">.</span> unpack) qLst <span class="co">-- получаем список ключей (можно было проще)</span>
+ <span class="kw">case</span> (toDelete,toApprove) <span class="kw">of</span> <span class="co">-- получаем выбранное действие</span>
+ (<span class="kw">Just</span> _, <span class="kw">Nothing</span>) <span class="ot">-&gt;</span> delete' qlst'
+ (<span class="kw">Nothing</span>, <span class="kw">Just</span> _) <span class="ot">-&gt;</span> approve' qlst'
+ (_,_) <span class="ot">-&gt;</span> <span class="kw">do</span>
+ setMessage [shamlet<span class="fu">|</span><span class="dt">Invalid</span> command<span class="fu">|</span>]
+ toMaster <span class="ot">&lt;-</span> getRouteToMaster <span class="co">-- редиректим пользователя</span>
+ redirect <span class="fu">$</span> toMaster <span class="dt">QuoteAbyssListR</span>
+ <span class="kw">where</span>
+ delete' list <span class="fu">=</span> <span class="kw">do</span>
+ runDB <span class="fu">$</span> <span class="fu">mapM</span> delete list
+ setMessage [shamlet<span class="fu">|</span>Цитаты были удалены|]
+ approve' list <span class="fu">=</span> <span class="kw">do</span>
+ runDB <span class="fu">$</span> <span class="fu">mapM</span> (<span class="fu">flip</span> update [<span class="dt">QuoteApproved</span> <span class="fu">=.</span> <span class="kw">True</span>]) list
+ setMessage [shamlet<span class="fu">|</span>Цитаты были опубликованы|]</code></pre>
+<h1 id="дополнительные-возможности">Дополнительные возможности</h1>
+<h2 id="rss">RSS</h2>
+<p>Yesod поддерживает автоматическое создание rss лент в виде RSS и ATOM в зависимости от заголовков посылаемых клиентом.</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">getQuoteFeedR ::</span> <span class="dt">Handler</span> <span class="dt">RepAtomRss</span>
+getQuoteFeedR <span class="fu">=</span> <span class="kw">do</span>
+ quotes <span class="ot">&lt;-</span> runDB <span class="fu">$</span> selectList [ <span class="dt">QuoteApproved</span><span class="fu">==.</span><span class="kw">True</span>]
+ [ <span class="dt">Desc</span> <span class="dt">QuoteTimestamp</span>
+ , <span class="dt">LimitTo</span> <span class="dv">100</span>
+ ]
+ newsFeed <span class="dt">Feed</span>
+ { feedTitle <span class="fu">=</span> <span class="st">&quot;Gentoo.ru Quotes&quot;</span>
+ , feedLinkSelf <span class="fu">=</span> <span class="dt">QuoteFeedR</span>
+ , feedLinkHome <span class="fu">=</span> <span class="dt">HomeR</span>
+ , feedDescription <span class="fu">=</span> <span class="st">&quot;Description&quot;</span>
+ , feedLanguage <span class="fu">=</span> <span class="st">&quot;ru&quot;</span>
+ , feedUpdated <span class="fu">=</span> (quoteTimestamp <span class="fu">$</span> entityVal <span class="fu">$</span> <span class="fu">head</span> <span class="fu">$</span> quotes)
+ , feedEntries <span class="fu">=</span> (<span class="fu">map</span> toFeed quotes)
+ }
+ <span class="kw">where</span>
+ toFeed (<span class="dt">Entity</span> i q) <span class="fu">=</span>
+ <span class="dt">FeedEntry</span>
+ { feedEntryLink <span class="fu">=</span> <span class="dt">QuoteShowR</span> i
+ , feedEntryUpdated <span class="fu">=</span> quoteTimestamp q
+ , feedEntryTitle <span class="fu">=</span> (<span class="st">&quot;Цитата №&quot;</span> <span class="ot">`append`</span> (toPathPiece i))
+ , feedEntryContent <span class="fu">=</span> (toHtml <span class="fu">$</span> quoteText q)
+ }</code></pre>
+<h2 id="создание-архива">Создание архива</h2>
+<p>Для создания архива используется потоковое api получения данных из базы, архивирования и записи в файл, таким образом можно гарантировать, то что программа не начнёт использовать слишком много ресурсов</p>
+<pre class="sourceCode haskell"><code class="sourceCode haskell">createFile <span class="fu">=</span> <span class="kw">do</span>
+ (qC, vC) <span class="ot">&lt;-</span> runDB <span class="fu">$</span> <span class="kw">do</span>
+ a <span class="ot">&lt;-</span> count [<span class="dt">QuoteApproved</span> <span class="fu">==.</span> <span class="kw">True</span>]
+ b <span class="ot">&lt;-</span> selectFirst [] [ <span class="dt">Desc</span> <span class="dt">TarballTimestamp</span>]
+ <span class="fu">return</span> (a,<span class="fu">maybe</span> <span class="dv">0</span> (tarballNumquotes<span class="fu">.</span>entityVal) b)
+ when (qC<span class="fu">&gt;</span>vC<span class="dv">+32</span>) <span class="fu">$</span> <span class="kw">do</span>
+ time <span class="ot">&lt;-</span> liftIO <span class="fu">$</span> getCurrentTime
+ <span class="kw">let</span> y <span class="fu">=</span> getL year time
+ m <span class="fu">=</span> getL month time
+ d <span class="fu">=</span> getL day time
+ s <span class="fu">=</span> printf <span class="st">&quot;%02d%02d%02d&quot;</span> y m d
+ f <span class="fu">=</span> <span class="st">&quot;fortune-mod-gentoo-ru-&quot;</span><span class="fu">++</span>s<span class="fu">++</span><span class="st">&quot;.gz&quot;</span>
+ t <span class="fu">=</span> <span class="dt">Tarball</span>
+ { tarballFilename <span class="fu">=</span> S.pack f
+ , tarballNumquotes <span class="fu">=</span> qC
+ , tarballTimestamp <span class="fu">=</span> time
+ }
+ runDB <span class="fu">$</span> <span class="kw">do</span>
+ insert t
+ runResourceT <span class="fu">$</span> selectSource [<span class="dt">QuoteApproved</span> <span class="fu">==.</span> <span class="kw">True</span>] []
+ <span class="fu">$=</span> CL.map toText
+ <span class="fu">$</span> CL.map encodeUtf8
+ <span class="fu">=$</span> gzip
+ <span class="fu">=$</span> sinkFile (<span class="st">&quot;static/files/&quot;</span><span class="fu">++</span>f)
+
+
+<span class="ot">toText ::</span> <span class="dt">Entity</span> <span class="dt">Quote</span> <span class="ot">-&gt;</span> <span class="dt">Text</span>
+toText (<span class="dt">Entity</span> _ quote) <span class="fu">=</span>
+ S.concat [ (unTextarea <span class="fu">$</span> quoteText quote)
+ , <span class="st">&quot;\n&quot;</span>
+ , <span class="st">&quot; -- &quot;</span>
+ , (<span class="fu">maybe</span> <span class="st">&quot;&quot;</span> <span class="fu">id</span> <span class="fu">$</span> quoteAuthor quote)
+ , <span class="st">&quot; &quot;</span>
+ , (S.pack <span class="fu">$</span> <span class="fu">show</span> <span class="fu">$</span> quoteSource quote)
+ , <span class="st">&quot;\n%\n&quot;</span>
+ ]</code></pre>
+
+<div id="disqus_thread"></div>
+
+<script type="text/javascript">
+//
+/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
+var disqus_shortname = 'qnikst'; // required: replace example with your forum shortname
+
+/* * * DON'T EDIT BELOW THIS LINE * * */
+(function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+})();
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+//
+</script>
+
+
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
View
85 projects.html
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
+ <title>QnikstBlog - My projects and projects I involden in</title>
+ <link rel="stylesheet" type="text/css" href="./css/screen.css"></link>
+ </head>
+ <body>
+ <div id="header">
+ QnikstBlog - My projects and projects I involden in
+
+ <div id="navigation">
+ <a href="./index.html">Home</a>
+ <a href="./posts.html">All posts</a>
+ <a href="./projects.html">Projects</a>
+ <a href="./contact.html">Contact</a>
+ </div>
+ </div>
+
+ <h1 id="my-projects">My projects:</h1>
+<blockquote>
+<ul>
+<li><dl>
+<dt><a href="http://github.com/qnikst/kbdd/">kbdd</a></dt>
+<dd><p>small layout switching utility that stores each window layout</p>
+<table>
+<col width="13%"></col>
+<col width="15%"></col>
+<tbody>
+<tr class="odd">
+<td align="left">License</td>
+<td align="left">GPLv3</td>
+</tr>
+<tr class="even">
+<td align="left">Language</td>
+<td align="left">C + glib</td>
+</tr>
+<tr class="odd">
+<td align="left">state</td>
+<td align="left">unstable</td>
+</tr>
+</tbody>
+</table>
+</dd>
+</dl></li>
+<li><dl>
+<dt><a href="http://github.com/qnikst/numeric-ode/">numeric ODE solvers</a></dt>
+<dd><p>learning library to solve different ODE preserving integrals this project aim to be a testing field for solving</p>
+<table>
+<col width="13%"></col>
+<col width="15%"></col>
+<tbody>
+<tr class="odd">
+<td align="left">License</td>
+<td align="left">BSD</td>
+</tr>
+<tr class="even">
+<td align="left">Language</td>
+<td align="left">haskell</td>
+</tr>
+<tr class="odd">
+<td align="left">state</td>
+<td align="left">unstable</td>
+</tr>
+</tbody>
+</table>
+</dd>
+</dl></li>
+</ul>
+</blockquote>
+<h1 id="projects-i-involded">Projects I involded:</h1>
+<blockquote>
+<ul>
+<li><a href="http://github.com/gentoo-haskell/hackport">hackport</a> tool for creating ebuilds from hackage</li>
+</ul>
+</blockquote>
+
+ <div id="footer">
+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>
+  
+ Blog comments powered by <a href="http://disqus.com" class="dsq-brlink"><span class="logo-disqus">Disqus</span></a>
+ </div>
+ </body>
+</html>
Please sign in to comment.
Something went wrong with that request. Please try again.