<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Planet Haskell (JP)</title><id>https://matsubara0507.github.io/planet-haskell-jp-demo/feed.xml</id><updated>2020-07-20T09:24:33+09:00</updated><link href="https://matsubara0507.github.io/planet-haskell-jp-demo"/><entry><id>https://kakkun61.hatenablog.com/entry/2020/07/20/Elm_%E3%81%A7%E3%83%9E%E3%83%86%E3%83%AA%E3%82%A2%E3%83%AB%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%81%AA%E3%82%A6%E3%82%A7%E3%83%96%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%9F</id><title type="text">Elm でマテリアルデザインなウェブアプリを作った</title><updated>2020-07-20T09:24:33+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/07/20/Elm_%E3%81%A7%E3%83%9E%E3%83%86%E3%83%AA%E3%82%A2%E3%83%AB%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%81%AA%E3%82%A6%E3%82%A7%E3%83%96%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%9F"/><summary type="html">アプリ概要 アプリとしてはニッチな用途で、写真用のモノクロネガフィルムを自家現像するときに便利なタイマーアプリです。下記は埋め込まれた実際に動くアプリです。 Photo Film Dev で公開しています。 時間配分をレシピと呼んでいますが、レシピはサーバーに保存されるためログインすれば複数の端末でアプリを使用できます。 今はレシピは自分のアカウントでしか見れないですが別のアカウントに共有する機能が作れたらなと考えています。 技術構成 ソースコードは GitHub に GPL3 で提供しています。 github.com アプリの技術構成としては次の通りです。 クライアント HTML/CSS/J…</summary></entry><entry><id>https://kurokawh.blogspot.com/2018/02/windows-windows10.html</id><title type="text">[windows] Windows10セットアップ・設定項目のメモ</title><updated>2020-07-16T12:08:20.505+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2018/02/windows-windows10.html"/><summary type="text">Windows10セットアップ時の設定項目、インストールアプリの備忘録。


スタートメニュー・タスクバーの設定

タスクバーの設定 

小さいタスクバーボタンを使う：オン 
[スタート]ボタンを右クリックするかWindowsキー＋Xキーを押したときに表示されるメニューで、コマンドプロンプトをWindows PowerShellに置き換える：オフ
タスクバーボタンを結合する

「タスクバーに入りきらない場合」を選択

タスクバーをすべての ディスプレイに表示する：オフ



 Quick Launcherを表示する

クイック起動を復活する 
Windows 10 タスクバーにクイック起動を表示する

スタートメニューにコントロールパネルを表示する

「Windows 10」のコントロールパネルを表示する方法について

スタートメニューにピン止めするアプリ：

Windowsシステム</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2020/07/09/100000</id><title type="text">gojqのパーサーを書き直しました</title><updated>2020-07-09T10:00:04+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2020/07/09/100000"/><summary type="html">jqはJSONを絞り込むツールですが、実はれっきとしたプログラミング言語です。 算術演算子、論理演算子、分岐構文、try・catch、そして関数定義があり、ループは再帰関数で実装します。 単に .foo とか .[0] とかでJSONを辿るだけのツールだと思われている方は、builtin関数の定義を見ていただくと良いかと思います。 selectやmapのように、よく使われる関数でさえ内部実装になっていない (Cで書かれていない) のは面白いですね。 jqのクエリを思ったように書けないという経験から、jqをより深く知るためにGo言語で再実装したのがgojqです。 去年の4月から開発を始め、8月に…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/07/07/Windows_Terminal_%E3%81%AB_MSYS2/MinGW64_%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B</id><title type="text">Windows Terminal に MSYS2/MinGW64 を追加する</title><updated>2020-07-07T00:39:02+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/07/07/Windows_Terminal_%E3%81%AB_MSYS2/MinGW64_%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B"/><summary type="html">Windows 10 2004 にしたので Windows Terminal をさわってみた。自分の用途だと Cmder はもう使わなくていいなと思う。 さて、Windows Terminal に MSYS2/MinGW64 を追加したのでその設定を示す。 { …, "profiles": { …, "list": [ …, { "guid": "{43257a9a-8d31-4208-8ed4-3d4365d44bd1}", "name": "MSYS2/MinGW64", "commandline": "%ChocolateyToolsLocation%\\msys64\\msys2_sh…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/07/06/Windows_%E3%81%AE%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC%E3%81%AB%E3%83%89%E3%83%83%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E3%82%89%E3%81%AA</id><title type="text">Windows のホームフォルダーにドットファイルを作らないでほしい</title><updated>2020-07-07T00:06:56+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/07/06/Windows_%E3%81%AE%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC%E3%81%AB%E3%83%89%E3%83%83%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E3%82%89%E3%81%AA"/><summary type="html">郷に従ってほしい pic.twitter.com/NzIep3qJcK— 岡本和樹 (@kakkun61) 2020年6月26日 Windows ではファイル名の先頭にドットを付けるだけでは隠しファイルにならないのでユーザーのホームフォルダーを汚染することになる。 だいたいの場合では LOCALAPPDATA 環境変数の示す場所にソフトウェア名のフォルダーを作ってその下を自由に使えばいい。 LOCALAPPDATA の示す場所は普通 C:\Users\kazuki\AppData\Local といったぐあいだが、ユーザーが変えている場合もあるので固定パスにするのはよろしくない。 また、隠しファ…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2020-07-02-read-featherweight-go.html</id><title type="text">Featherweight Go を読んでみた</title><updated>2020-07-02T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2020-07-02-read-featherweight-go.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;Go言語にジェネリクスを導入するために，その形式的な議論を研究した論文「&lt;a href="https://arxiv.org/abs/2005.11710"&gt;Featherweight Go&lt;/a&gt;」が6月頭に発表されました． せっかくなので（久々に）全訳をしながら丁寧に読んでみたので，それを簡単にまとめることにします．&lt;/p&gt;
&lt;p&gt;可能な限りGo言語に馴染みのない人や，プログラミング言語の形式的な議論に馴染みのない人でも理解できるようにしてみます．&lt;/p&gt;
&lt;h4 id="注意"&gt;注意&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;僕は英語がとても苦手です（DeepLを駆使しても3週間かかりました）&lt;/li&gt;
&lt;li&gt;僕はGoでアプリケーションを少し書いていますがコアについては全く詳しくありません&lt;/li&gt;
&lt;li&gt;僕は言語の形式的な議論を院生時代にやってましたが卒業して数年経ちます&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;なので間違ってる可能性も十分に考慮してください．&lt;/p&gt;
&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Goにジェネリクスを導入する新しいデザインを提案：
&lt;ul&gt;
&lt;li&gt;インターフェースと型アサーションを駆使する方法&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;新デザインを形式的に議論するために FG と FGG を定義
&lt;ul&gt;
&lt;li&gt;FG：Goの極めて小さいモデル&lt;/li&gt;
&lt;li&gt;FGG：FG をジェネリクスで拡張&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;単相化（Monomorphisation）というFGGからFGの変換を定義
&lt;ul&gt;
&lt;li&gt;単相化は型パラメーターを具体化した実装を必要な型だけ完全に列挙する方法&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rhu1/fgg"&gt;これらは全てGoでプロトタイプ実装した&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;加えて，この Go のジェネリクスは Expression Problem の解法にもなり得るという議論もある．&lt;/p&gt;
&lt;h2 id="前提知識"&gt;前提知識&lt;/h2&gt;
&lt;h3 id="featherweight-java"&gt;Featherweight Java&lt;/h3&gt;
&lt;p&gt;1999年に出された論文に「&lt;a href="https://dl.acm.org/doi/abs/10.1145/320385.320395"&gt;Featherweight Java&lt;/a&gt;」というものがある． 僕はこの論文を読んではいないがどうやら，この論文も FJ という Java の小さな言語モデルを定義し，それをジェネリクスで拡張した FGJ を定義し，FGJ から FJ への変換の仕方を定義して形式的な議論を与えている．&lt;/p&gt;
&lt;p&gt;Featherweight Go でも言及されているとおり，Featherweight Go は議論の展開の仕方に Featherweight Java を参考としている．&lt;/p&gt;
&lt;h3 id="goの型"&gt;Goの型&lt;/h3&gt;
&lt;p&gt;Goで型と呼べるものは大きく分けて2つ，構造体（structure）とインターフェース（interface）がある：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;構造体：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;type [name] structure { ... }&lt;/code&gt; という形で宣言&lt;/li&gt;
&lt;li&gt;&lt;code&gt;...&lt;/code&gt; にフィールド名と型を列挙（いわゆるレコード型）&lt;/li&gt;
&lt;li&gt;フィールドアクセスはドット記法（e.g. &lt;code&gt;x.m()&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;インターフェース：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;type [name] interface { ... }&lt;/code&gt; という形で宣言&lt;/li&gt;
&lt;li&gt;&lt;code&gt;...&lt;/code&gt; にメソッド仕様（method specification，メソッド名 + 型）を列挙&lt;/li&gt;
&lt;li&gt;列挙したメソッドを定義した型はインターフェースのサブタイプになる（いわゆる構造的部分型）&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="型アサーション"&gt;型アサーション&lt;/h3&gt;
&lt;p&gt;Goでの型キャストっぽい機能． インターフェースで指定されてる型からサブタイプへと変換する．&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Hoge &lt;span class="kw"&gt;interface&lt;/span&gt; { ... }&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Fuga &lt;span class="kw"&gt;struct&lt;/span&gt; { ... }&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4"&gt;&lt;/a&gt;&lt;span class="co"&gt;// Fuga は Hoge を実装しているとする&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; piyo(x Hoge) *Fuga {  &lt;span class="co"&gt;// *X はX型のポインタ型&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6"&gt;&lt;/a&gt;    y, ok := x.(Fuga)      &lt;span class="co"&gt;// これが型アサーション&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; !ok {               &lt;span class="co"&gt;// 型アサーションに失敗したときに false を返す&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="ot"&gt;nil&lt;/span&gt;         &lt;span class="co"&gt;// nil はポインタのゼロ値&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-9"&gt;&lt;a href="#cb1-9"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb1-10"&gt;&lt;a href="#cb1-10"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; &amp;amp;y&lt;/span&gt;
&lt;span id="cb1-11"&gt;&lt;a href="#cb1-11"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;piyo&lt;/code&gt; 関数は &lt;code&gt;Hoge&lt;/code&gt; インターフェースを実装した型の値であれば，なんでも引数として与えることができる． 型アサーションの &lt;code&gt;ok&lt;/code&gt; は省略することができ，その場合は型アサーションに失敗したときに実行時エラーとなる．&lt;/p&gt;
&lt;h3 id="用語と翻訳"&gt;用語と翻訳&lt;/h3&gt;
&lt;p&gt;基本的に，この分野の入門書として名高い[要出典]「型システム入門（原題：Type and Programming Language，略して TaPL）」の訳し方を参考にする． TaPL には無い用語は次のように翻訳したが，Go ジェネリクスが市民権を得たときには別の翻訳が宛てがわれるかもしれない：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monomorphisation：単相化
&lt;ul&gt;
&lt;li&gt;Polymorphism（多相性）の対義語が Monomorphism（単相性）というらしい&lt;/li&gt;
&lt;li&gt;Rust でも Monomorphization という用語を単相化と訳していた&lt;/li&gt;
&lt;li&gt;（この表記の揺れはおそらくイギリス綴りかアメリカ綴りかの差？）&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Bound：境界
&lt;ul&gt;
&lt;li&gt;機能は Java の Bounded Types（境界型などと訳されている）に近い&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-lang-ja/the-rust-programming-language-ja/issues/153"&gt;Rust でも色々議論した結果 Bound を「境界」と訳した&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;また，プログラミング言語の形式的な議論で頻出する用語について簡単に解説する：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;構文（Syntax）:
&lt;ul&gt;
&lt;li&gt;ある言語においてプログラムの「正しい記述方法」を定義したもの&lt;/li&gt;
&lt;li&gt;一般的に BNF（バッカス・ナウア記法）で定義する&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;意味論（Semantics）:
&lt;ul&gt;
&lt;li&gt;ある言語においてプログラムが「どのように実行されるか」を定義したもの&lt;/li&gt;
&lt;li&gt;いくつか定義の仕方があるがこの論文では簡約規則（操作的意味論）を利用している&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;型付け規則（Typing Rule）:
&lt;ul&gt;
&lt;li&gt;式 &lt;span class="math inline"&gt;&lt;em&gt;e&lt;/em&gt;&lt;/span&gt; に対して「正しい」型の付け方の規則&lt;/li&gt;
&lt;li&gt;正しく型付けされているとはつまり静的型検査が通るような状態&lt;/li&gt;
&lt;li&gt;一般的に &lt;span class="math inline"&gt;&lt;em&gt;Γ&lt;/em&gt; ⊢ &lt;em&gt;e&lt;/em&gt; : &lt;em&gt;t&lt;/em&gt;&lt;/span&gt; とかく（&lt;span class="math inline"&gt;&lt;em&gt;Γ&lt;/em&gt;&lt;/span&gt; は環境で変数がなんの型なのかを保存している）&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;簡約（Reduction）:
&lt;ul&gt;
&lt;li&gt;ある式 &lt;span class="math inline"&gt;&lt;em&gt;e&lt;/em&gt;&lt;/span&gt; から別の式（値）への変換&lt;/li&gt;
&lt;li&gt;一般的に &lt;span class="math inline"&gt;&lt;em&gt;e&lt;/em&gt; → &lt;em&gt;e&lt;/em&gt;′&lt;/span&gt; のように矢印を使う&lt;/li&gt;
&lt;li&gt;例: &lt;span class="math inline"&gt;1 + 2 * 3 → 1 + 6 → 7&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;型安全性（Safety）:
&lt;ul&gt;
&lt;li&gt;健全性（Soundness）とも呼ぶ&lt;/li&gt;
&lt;li&gt;正しく型付けされた項は「おかしくなる」ことがないということ&lt;/li&gt;
&lt;li&gt;「おかしくなる」の定義は言語モデルによって異なる（例：行き詰まり状態）&lt;/li&gt;
&lt;li&gt;進行定理 + 保存定理 なのでこの2つを証明するのが一般的&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;進行定理（Progress）:
&lt;ul&gt;
&lt;li&gt;正しく型付けされた項は行き詰まり状態では無い&lt;/li&gt;
&lt;li&gt;行き詰まり状態：値でもないし簡約もできない状態&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;保存定理（Preservation）:
&lt;ul&gt;
&lt;li&gt;正しく型付けされた項が評価できるならば，評価後の項も正しく型付けされる&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;双模倣性（Bisimulation）:
&lt;ul&gt;
&lt;li&gt;並行モデルでよく出てくる性質（今回の中では最もマイナーな性質）&lt;/li&gt;
&lt;li&gt;ざっくりいうと，2つのモデルが同じように振舞うという性質&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="プログラミング言語の形式的な議論"&gt;プログラミング言語の形式的な議論&lt;/h3&gt;
&lt;p&gt;なぜ，わざわざ形式的な議論（証明を与える）をするのか． TaPL の第19章「事例: Featherweight Java」にはこう書いてある：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;プログラミング言語のような現実世界の複雑な人工物を設計するには，形式的にモデル化することが大きな手助けとなる．形式モデルを使うと，設計のある側面を正確に説明したり，その性質を記述・証明したり，そこまでしないと見落としかねない問題に注意を向けたりできる．&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;現に，Featherweight Go ではFGGがある「前提条件」のもとで必ず単相化できることを証明しており，その結果，実際のジェネリクス付きGoの「正しい」静的検査（コンパイル）を定義できた（この条件がないと，単相化が停止しない可能性がある）．&lt;/p&gt;
&lt;h3 id="expression-problem"&gt;Expression Problem&lt;/h3&gt;
&lt;p&gt;今回は割愛する（ググって）が，本論文で提案するジェネリクス付きGoは Expression Problem に対する解法になっていると主張している（個人的には，あまり Go っぽい書き方じゃない気がするけど笑）．&lt;/p&gt;
&lt;h2 id="goで多相的な実装をする"&gt;Goで多相的な実装をする&lt;/h2&gt;
&lt;p&gt;現状のGoでも多相的な実装をする方法がいくつかある． 今回目を付けたのが，インターフェースと型アサーションを使った方法だ．&lt;/p&gt;
&lt;p&gt;例えば，高階関数を次のように表現できる：&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Any &lt;span class="kw"&gt;interface&lt;/span&gt; {}&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Function &lt;span class="kw"&gt;interface&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4"&gt;&lt;/a&gt;    Apply(x Any) Any&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7"&gt;&lt;/a&gt;&lt;span class="co"&gt;// g(f(x)) を表現&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; compose &lt;span class="kw"&gt;struct&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9"&gt;&lt;/a&gt;    f Function&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="#cb2-10"&gt;&lt;/a&gt;    g Function&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="#cb2-11"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb2-12"&gt;&lt;a href="#cb2-12"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this compose) Apply(x Any) Any {&lt;/span&gt;
&lt;span id="cb2-13"&gt;&lt;a href="#cb2-13"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; this.g.Apply(this.f.Apply(x))&lt;/span&gt;
&lt;span id="cb2-14"&gt;&lt;a href="#cb2-14"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb2-15"&gt;&lt;a href="#cb2-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-16"&gt;&lt;a href="#cb2-16"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; incr &lt;span class="kw"&gt;struct&lt;/span&gt; { n &lt;span class="dt"&gt;int&lt;/span&gt; } &lt;span class="co"&gt;// nだけインクリメントする&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-17"&gt;&lt;a href="#cb2-17"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this incr) Apply(x Any) Any {&lt;/span&gt;
&lt;span id="cb2-18"&gt;&lt;a href="#cb2-18"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; x.(&lt;span class="dt"&gt;int&lt;/span&gt;) + this.n&lt;/span&gt;
&lt;span id="cb2-19"&gt;&lt;a href="#cb2-19"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb2-20"&gt;&lt;a href="#cb2-20"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-21"&gt;&lt;a href="#cb2-21"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; pos &lt;span class="kw"&gt;struct&lt;/span&gt; {} &lt;span class="co"&gt;// 正数なら真が返る&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-22"&gt;&lt;a href="#cb2-22"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this pos) Apply(x Any) Any {&lt;/span&gt;
&lt;span id="cb2-23"&gt;&lt;a href="#cb2-23"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; x.(&lt;span class="dt"&gt;int&lt;/span&gt;) &amp;gt; &lt;span class="dv"&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-24"&gt;&lt;a href="#cb2-24"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb2-25"&gt;&lt;a href="#cb2-25"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-26"&gt;&lt;a href="#cb2-26"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; main() {&lt;/span&gt;
&lt;span id="cb2-27"&gt;&lt;a href="#cb2-27"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; f Function = compose{incr{-&lt;span class="dv"&gt;5&lt;/span&gt;}, pos{}}&lt;/span&gt;
&lt;span id="cb2-28"&gt;&lt;a href="#cb2-28"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; b &lt;span class="dt"&gt;bool&lt;/span&gt; = f.Apply(&lt;span class="dv"&gt;3&lt;/span&gt;).(&lt;span class="dt"&gt;bool&lt;/span&gt;) &lt;span class="co"&gt;// false&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-29"&gt;&lt;a href="#cb2-29"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このコードは，既存の Go としても完全に正しい． &lt;code&gt;Any&lt;/code&gt; インターフェースは実装すべきメソッド仕様を一つも持たないので，全ての型が実装していることになる． 無論，本当は &lt;code&gt;int&lt;/code&gt; や &lt;code&gt;bool&lt;/code&gt; であるべきところが &lt;code&gt;Any&lt;/code&gt; になっていたり，&lt;code&gt;Any&lt;/code&gt; な型同士の区別が付かなくなっていたりする問題がある． だがしかし，それがコンパイル時に検査できるようになったらどうだろうか．新しいデザインがまさにそういう形式になっている．&lt;/p&gt;
&lt;h2 id="fg-と-fgg"&gt;FG と FGG&lt;/h2&gt;
&lt;p&gt;論文では，それぞれの構文と型付け規則，簡約規則を定義し，構文的正しさの検証規則の定義と，保存定理と進行定理を証明している（すなわち型安全であることを示している）． ここでは2つの構文だけ紹介する．&lt;/p&gt;
&lt;h3 id="fgの構文"&gt;FGの構文&lt;/h3&gt;
&lt;p&gt;&lt;span class="math inline"&gt;&lt;em&gt;x̄&lt;/em&gt;&lt;/span&gt; のような上線付きの記法は，ある形式の項の「列」であることを示している． 例えば &lt;span class="math inline"&gt;&lt;em&gt;x̄&lt;/em&gt;&lt;/span&gt; の場合は &lt;span class="math inline"&gt;&lt;em&gt;x&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt;, &lt;em&gt;x&lt;/em&gt;&lt;sub&gt;2&lt;/sub&gt;, ...&lt;em&gt;x&lt;/em&gt;&lt;sub&gt;&lt;em&gt;n&lt;/em&gt;&lt;/sub&gt;&lt;/span&gt; を意味している．&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/read-featherweight-go/fg.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;プログラム &lt;span class="math inline"&gt;&lt;em&gt;P&lt;/em&gt;&lt;/span&gt; は，Go の形式にならって定義されているが，論文中では諸々省略して &lt;span class="math inline"&gt;&lt;em&gt;D̄&lt;/em&gt; ⊳ &lt;em&gt;e&lt;/em&gt;&lt;/span&gt; と記述することもある．&lt;/p&gt;
&lt;p&gt;FG は極めてコンパクトな Go のサブセットである． そのため，有効な式は変数・メソッド呼び出し・構造体リテラル・フィールド選択・型アサーションの5つしかない． 対して型（構造体・インターフェース）に関する構文はかなり充実している．&lt;/p&gt;
&lt;h2 id="section"&gt;&lt;/h2&gt;
&lt;p&gt;FG には他に型付け規則と簡約規則がある．特に型付け規則の一部である，構造的部分型を表現した規則 &lt;span class="math inline"&gt;&lt;em&gt;t&lt;/em&gt; &amp;lt;  : &lt;em&gt;u&lt;/em&gt;&lt;/span&gt; は重要だ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math inline"&gt;&lt;em&gt;u&lt;/em&gt;&lt;/span&gt; が構造体 &lt;span class="math inline"&gt;&lt;em&gt;t&lt;/em&gt;&lt;sub&gt;&lt;em&gt;S&lt;/em&gt;&lt;/sub&gt;&lt;/span&gt; の場合は &lt;span class="math inline"&gt;&lt;em&gt;t&lt;/em&gt;&lt;sub&gt;&lt;em&gt;S&lt;/em&gt;&lt;/sub&gt;&lt;/span&gt; 自信のみがサブタイプになる（i.e. &lt;span class="math inline"&gt;&lt;em&gt;t&lt;/em&gt;&lt;sub&gt;&lt;em&gt;S&lt;/em&gt;&lt;/sub&gt; &amp;lt;  : &lt;em&gt;t&lt;/em&gt;&lt;sub&gt;&lt;em&gt;S&lt;/em&gt;&lt;/sub&gt;&lt;/span&gt;）&lt;/li&gt;
&lt;li&gt;&lt;span class="math inline"&gt;&lt;em&gt;u&lt;/em&gt;&lt;/span&gt; がインターフェース &lt;span class="math inline"&gt;&lt;em&gt;t&lt;/em&gt;&lt;sub&gt;&lt;em&gt;I&lt;/em&gt;&lt;/sub&gt;&lt;/span&gt; の場合は &lt;span class="math inline"&gt;&lt;em&gt;m&lt;/em&gt;&lt;em&gt;e&lt;/em&gt;&lt;em&gt;t&lt;/em&gt;&lt;em&gt;h&lt;/em&gt;&lt;em&gt;o&lt;/em&gt;&lt;em&gt;d&lt;/em&gt;&lt;em&gt;s&lt;/em&gt;(&lt;em&gt;t&lt;/em&gt;) ⊇ &lt;em&gt;m&lt;/em&gt;&lt;em&gt;e&lt;/em&gt;&lt;em&gt;t&lt;/em&gt;&lt;em&gt;h&lt;/em&gt;&lt;em&gt;o&lt;/em&gt;&lt;em&gt;d&lt;/em&gt;&lt;em&gt;s&lt;/em&gt;(&lt;em&gt;t&lt;/em&gt;&lt;sub&gt;&lt;em&gt;I&lt;/em&gt;&lt;/sub&gt;)&lt;/span&gt; を満たすような &lt;span class="math inline"&gt;&lt;em&gt;t&lt;/em&gt;&lt;/span&gt; のみがサブタイプになる（i.e. &lt;span class="math inline"&gt;&lt;em&gt;t&lt;/em&gt;&lt;sub&gt;&lt;em&gt;S&lt;/em&gt;&lt;/sub&gt; &amp;lt;  : &lt;em&gt;t&lt;/em&gt;&lt;sub&gt;&lt;em&gt;I&lt;/em&gt;&lt;/sub&gt;&lt;/span&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ここで &lt;span class="math inline"&gt;&lt;em&gt;m&lt;/em&gt;&lt;em&gt;e&lt;/em&gt;&lt;em&gt;t&lt;/em&gt;&lt;em&gt;h&lt;/em&gt;&lt;em&gt;o&lt;/em&gt;&lt;em&gt;d&lt;/em&gt;&lt;em&gt;s&lt;/em&gt;(&lt;em&gt;t&lt;/em&gt;)&lt;/span&gt; という補助関数は型 &lt;span class="math inline"&gt;&lt;em&gt;t&lt;/em&gt;&lt;/span&gt; に定義されているメソッドのメソッド仕様の集合である（重複しないという前提）． また，メソッド仕様の等価性には変数名は関係しない（つまり，メソッド名・引数の型・返り値の型が一致するかどうかをみる）． この部分型関係 &lt;span class="math inline"&gt; &amp;lt; :&lt;/span&gt; は，メソッド呼び出しや構造体リテラルの引数を適用する部分や，型アサーションの型付け規則で利用される．&lt;/p&gt;
&lt;h3 id="fggの構文"&gt;FGGの構文&lt;/h3&gt;
&lt;p&gt;前述したとおり，FGG は FG をジェネリクスで拡張した言語である． なので下記の構文規則のうち，FG からの拡張に当たる部分を赤でハイライトしてある．&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/read-featherweight-go/fgg.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;最も大きな変更として型宣言とメソッド宣言（メソッドシグネチャ）が型引数 &lt;span class="math inline"&gt;&lt;em&gt;Φ&lt;/em&gt;&lt;/span&gt; も取りうるようになったことだ． この型引数がまさにジェネリクスである． 手っ取り早く具体的なコードを見てみよう． 下記のコードは「Goで多相的な実装をする」を FGG 風の記法で置き換えたものだ（風というのは &lt;code&gt;+&lt;/code&gt; や &lt;code&gt;&amp;gt;&lt;/code&gt; や &lt;code&gt;int&lt;/code&gt; や &lt;code&gt;bool&lt;/code&gt; は FGG にはまだ無いため）：&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Any &lt;span class="kw"&gt;interface&lt;/span&gt; {}&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Function(&lt;span class="kw"&gt;type&lt;/span&gt; a Any, b Any) &lt;span class="kw"&gt;interface&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4"&gt;&lt;/a&gt;    Apply(x a) b&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7"&gt;&lt;/a&gt;&lt;span class="co"&gt;// g(f(x)) を表現&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; compose(&lt;span class="kw"&gt;type&lt;/span&gt; a Any, b Any, c Any) &lt;span class="kw"&gt;struct&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9"&gt;&lt;/a&gt;    f Function(a, b)&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10"&gt;&lt;/a&gt;    g Function(b, c)&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this compose(&lt;span class="kw"&gt;type&lt;/span&gt; a Any, b Any, c Any)) Apply(x a) c {&lt;/span&gt;
&lt;span id="cb3-13"&gt;&lt;a href="#cb3-13"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; this.g.Apply(this.f.Apply(x))&lt;/span&gt;
&lt;span id="cb3-14"&gt;&lt;a href="#cb3-14"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb3-15"&gt;&lt;a href="#cb3-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-16"&gt;&lt;a href="#cb3-16"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; incr &lt;span class="kw"&gt;struct&lt;/span&gt; { n &lt;span class="dt"&gt;int&lt;/span&gt; } &lt;span class="co"&gt;// nだけインクリメントする&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-17"&gt;&lt;a href="#cb3-17"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this incr) Apply(x &lt;span class="dt"&gt;int&lt;/span&gt;) &lt;span class="dt"&gt;int&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb3-18"&gt;&lt;a href="#cb3-18"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; x + this.n&lt;/span&gt;
&lt;span id="cb3-19"&gt;&lt;a href="#cb3-19"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb3-20"&gt;&lt;a href="#cb3-20"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-21"&gt;&lt;a href="#cb3-21"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; pos &lt;span class="kw"&gt;struct&lt;/span&gt; {} &lt;span class="co"&gt;// 正数なら真が返る&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-22"&gt;&lt;a href="#cb3-22"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this pos) Apply(x &lt;span class="dt"&gt;int&lt;/span&gt;) &lt;span class="dt"&gt;bool&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb3-23"&gt;&lt;a href="#cb3-23"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; x &amp;gt; &lt;span class="dv"&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-24"&gt;&lt;a href="#cb3-24"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb3-25"&gt;&lt;a href="#cb3-25"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-26"&gt;&lt;a href="#cb3-26"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; main() {&lt;/span&gt;
&lt;span id="cb3-27"&gt;&lt;a href="#cb3-27"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; f Function(&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;bool&lt;/span&gt;) = compose(&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;bool&lt;/span&gt;){incr{-&lt;span class="dv"&gt;5&lt;/span&gt;}, pos{}}&lt;/span&gt;
&lt;span id="cb3-28"&gt;&lt;a href="#cb3-28"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; b &lt;span class="dt"&gt;bool&lt;/span&gt; = f.Apply(&lt;span class="dv"&gt;3&lt;/span&gt;) &lt;span class="co"&gt;// false&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-29"&gt;&lt;a href="#cb3-29"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;なんと，このコードには型アサーションが一切出てこない． また，高階関数を表現するインターフェースで，ちゃんと引数と戻り値の型を区別することができている．&lt;/p&gt;
&lt;p&gt;構文の本質的な変更を見てみよう． インターフェースや構造体，メソッドの宣言に &lt;code&gt;(type a Any, b Any)&lt;/code&gt; というのが出てくるようになった． これがまさに型引数 &lt;span class="math inline"&gt;&lt;em&gt;Φ&lt;/em&gt;&lt;/span&gt; や &lt;span class="math inline"&gt;&lt;em&gt;Ψ&lt;/em&gt;&lt;/span&gt; に当たる． &lt;code&gt;a&lt;/code&gt; や &lt;code&gt;b&lt;/code&gt; の型パラメーターの後に記述している &lt;code&gt;Any&lt;/code&gt; は &lt;strong&gt;境界（bound）&lt;/strong&gt; と呼び，自由にインターフェースを置くことができる． 構造体リテラルやメソッド呼び出しで型引数に型を適用する場合や，部分型関係が成り立つ場合（&lt;code&gt;Apply(x int) bool&lt;/code&gt; の &lt;code&gt;int&lt;/code&gt; や &lt;code&gt;bool&lt;/code&gt; のこと）は，与えた型が境界のインターフェースのサブタイプになっている必要がある（今回の場合は &lt;code&gt;Any&lt;/code&gt; なのでどんな型でも良いが）． ここで重要になるのが，型引数の型パラメーターのスコープである：&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;// 型名やメソッド名の型パラメーターは内部のメソッドシグネチャで利用できる&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; List(&lt;span class="kw"&gt;type&lt;/span&gt; a Any) &lt;span class="kw"&gt;interface&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3"&gt;&lt;/a&gt;    Map(&lt;span class="kw"&gt;type&lt;/span&gt; b Any)(f Function(a, b)) List(b)&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb4-5"&gt;&lt;a href="#cb4-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-6"&gt;&lt;a href="#cb4-6"&gt;&lt;/a&gt;&lt;span class="co"&gt;// 型パラメーターを自身の境界で利用することもできる&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-7"&gt;&lt;a href="#cb4-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Eq(&lt;span class="kw"&gt;type&lt;/span&gt; a Eq(a)) &lt;span class="kw"&gt;interface&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb4-8"&gt;&lt;a href="#cb4-8"&gt;&lt;/a&gt;    Equal(that a) &lt;span class="dt"&gt;bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-9"&gt;&lt;a href="#cb4-9"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;インターフェースの型引数はメソッド仕様の型引数でも使うことはできるが，その逆はできない．&lt;/p&gt;
&lt;h2 id="単相化"&gt;単相化&lt;/h2&gt;
&lt;p&gt;いよいよ FGG から FG への変換方法をみていく． 論文では，単相化の規則を形式的に定義し，単相化したコードは構文的正しさが保存されることと，双模倣性を証明した．ここでは形式的な議論を割愛する．&lt;/p&gt;
&lt;h3 id="単相化の例"&gt;単相化の例&lt;/h3&gt;
&lt;p&gt;まずは例を見てみよう． 前述した FGG の &lt;code&gt;Function&lt;/code&gt; などの例を「単相化」で FG に変換すると次のようになる．&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Top &lt;span class="kw"&gt;struct&lt;/span&gt; {}&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; main() {&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; f Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; = compose&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;{incr{-&lt;span class="dv"&gt;5&lt;/span&gt;}, pos{}}&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; b &lt;span class="dt"&gt;bool&lt;/span&gt; = f.Apply(&lt;span class="dv"&gt;3&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; compose&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; &lt;span class="kw"&gt;struct&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9"&gt;&lt;/a&gt;    f Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span id="cb5-10"&gt;&lt;a href="#cb5-10"&gt;&lt;/a&gt;    g Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span id="cb5-11"&gt;&lt;a href="#cb5-11"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb5-12"&gt;&lt;a href="#cb5-12"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-13"&gt;&lt;a href="#cb5-13"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; &lt;span class="kw"&gt;interface&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb5-14"&gt;&lt;a href="#cb5-14"&gt;&lt;/a&gt;    Apply&amp;lt;&lt;span class="dv"&gt;0&lt;/span&gt;&amp;gt; Top&lt;/span&gt;
&lt;span id="cb5-15"&gt;&lt;a href="#cb5-15"&gt;&lt;/a&gt;    Apply(x &lt;span class="dt"&gt;int&lt;/span&gt;) &lt;span class="dt"&gt;int&lt;/span&gt;    &lt;/span&gt;
&lt;span id="cb5-16"&gt;&lt;a href="#cb5-16"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb5-17"&gt;&lt;a href="#cb5-17"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-18"&gt;&lt;a href="#cb5-18"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; &lt;span class="kw"&gt;interface&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb5-19"&gt;&lt;a href="#cb5-19"&gt;&lt;/a&gt;    Apply&amp;lt;&lt;span class="dv"&gt;1&lt;/span&gt;&amp;gt; Top&lt;/span&gt;
&lt;span id="cb5-20"&gt;&lt;a href="#cb5-20"&gt;&lt;/a&gt;    Apply(x &lt;span class="dt"&gt;int&lt;/span&gt;) &lt;span class="dt"&gt;bool&lt;/span&gt;    &lt;/span&gt;
&lt;span id="cb5-21"&gt;&lt;a href="#cb5-21"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb5-22"&gt;&lt;a href="#cb5-22"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-23"&gt;&lt;a href="#cb5-23"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; (this compose&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;) Apply(x &lt;span class="dt"&gt;int&lt;/span&gt;) &lt;span class="dt"&gt;bool&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb5-24"&gt;&lt;a href="#cb5-24"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; this.g.Apply(this.f.Apply(x))&lt;/span&gt;
&lt;span id="cb5-25"&gt;&lt;a href="#cb5-25"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb5-26"&gt;&lt;a href="#cb5-26"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; (this compose&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;int&lt;/span&gt;, &lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;) Apply&amp;lt;&lt;span class="dv"&gt;1&lt;/span&gt;&amp;gt;() Top {&lt;/span&gt;
&lt;span id="cb5-27"&gt;&lt;a href="#cb5-27"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Top{}&lt;/span&gt;
&lt;span id="cb5-28"&gt;&lt;a href="#cb5-28"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb5-29"&gt;&lt;a href="#cb5-29"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-30"&gt;&lt;a href="#cb5-30"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; incr &lt;span class="kw"&gt;struct&lt;/span&gt; { n &lt;span class="dt"&gt;int&lt;/span&gt; }&lt;/span&gt;
&lt;span id="cb5-31"&gt;&lt;a href="#cb5-31"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-32"&gt;&lt;a href="#cb5-32"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; (this incr) Apply(x &lt;span class="dt"&gt;int&lt;/span&gt;) &lt;span class="dt"&gt;int&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb5-33"&gt;&lt;a href="#cb5-33"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; x + this.n&lt;/span&gt;
&lt;span id="cb5-34"&gt;&lt;a href="#cb5-34"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb5-35"&gt;&lt;a href="#cb5-35"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this incr) Apply&amp;lt;&lt;span class="dv"&gt;0&lt;/span&gt;&amp;gt;() Top {&lt;/span&gt;
&lt;span id="cb5-36"&gt;&lt;a href="#cb5-36"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Top{}&lt;/span&gt;
&lt;span id="cb5-37"&gt;&lt;a href="#cb5-37"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb5-38"&gt;&lt;a href="#cb5-38"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-39"&gt;&lt;a href="#cb5-39"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; pos strcut {}&lt;/span&gt;
&lt;span id="cb5-40"&gt;&lt;a href="#cb5-40"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-41"&gt;&lt;a href="#cb5-41"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this pos) Apply(x &lt;span class="dt"&gt;int&lt;/span&gt;) &lt;span class="dt"&gt;bool&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb5-42"&gt;&lt;a href="#cb5-42"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; x &amp;gt; &lt;span class="dv"&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-43"&gt;&lt;a href="#cb5-43"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb5-44"&gt;&lt;a href="#cb5-44"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this incr) Apply&amp;lt;&lt;span class="dv"&gt;1&lt;/span&gt;&amp;gt;() Top {&lt;/span&gt;
&lt;span id="cb5-45"&gt;&lt;a href="#cb5-45"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Top{}&lt;/span&gt;
&lt;span id="cb5-46"&gt;&lt;a href="#cb5-46"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;大きな変更箇所として，&lt;code&gt;Function&amp;lt;int, int&amp;gt;&lt;/code&gt; のように &lt;code&gt;(,)&lt;/code&gt; が &lt;code&gt;&amp;lt;,&amp;gt;&lt;/code&gt; へ至る所でなっている． FGG のときの &lt;code&gt;(,)&lt;/code&gt; は内部の型は個別の型として認識されていたが，&lt;code&gt;&amp;lt;,&amp;gt;&lt;/code&gt; は &lt;code&gt;Function&amp;lt;int, int&amp;gt;&lt;/code&gt; で一つの型となり内部の型は区別されない．&lt;/p&gt;
&lt;p&gt;また，&lt;code&gt;Apply&amp;lt;0&amp;gt; Top&lt;/code&gt; のようなメソッドやメソッド仕様が追加されている． これは，部分型関係を正しく解決するためのダミーメソッドだ． 全てのメソッド宣言に対してダミーメソッドは追加で宣言され，インターフェースの全てのメソッド仕様に対してダミーメソッドのメソッド仕様が追加される． メソッド仕様の数字（&lt;code&gt;&amp;lt;0&amp;gt;&lt;/code&gt; とか &lt;code&gt;&amp;lt;1&amp;gt;&lt;/code&gt; とか）はメソッドの引数の型と返り値の型に対して一意に定まる（そのため &lt;code&gt;compose&lt;/code&gt; と &lt;code&gt;pos&lt;/code&gt; の &lt;code&gt;Apply&lt;/code&gt; メソッドの数字は同じになる）．&lt;/p&gt;
&lt;p&gt;ちなみに &lt;code&gt;Top&lt;/code&gt; 構造体はダミーメソッドのために追加された構造体だ．&lt;/p&gt;
&lt;h3 id="ダミーメソッドが有効な例"&gt;ダミーメソッドが有効な例&lt;/h3&gt;
&lt;p&gt;さて，上記の例ではダミーメソッドの有効性がわからないので，もう一つ例を示す． 前にちょっとだけ出てきた &lt;code&gt;List&lt;/code&gt; インターフェースの完全な例を示す． 下記は FGG でのコードだ．&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; List(&lt;span class="kw"&gt;type&lt;/span&gt; a Any) &lt;span class="kw"&gt;interface&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2"&gt;&lt;/a&gt;    Map(&lt;span class="kw"&gt;type&lt;/span&gt; b Any)(f Function(a, b)) List(b)&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Nil(&lt;span class="kw"&gt;type&lt;/span&gt; a Any) &lt;span class="kw"&gt;struct&lt;/span&gt; {}&lt;/span&gt;
&lt;span id="cb6-6"&gt;&lt;a href="#cb6-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Cons(&lt;span class="kw"&gt;type&lt;/span&gt; a Any) &lt;span class="kw"&gt;struct&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb6-7"&gt;&lt;a href="#cb6-7"&gt;&lt;/a&gt;    head a&lt;/span&gt;
&lt;span id="cb6-8"&gt;&lt;a href="#cb6-8"&gt;&lt;/a&gt;    tail List(a)&lt;/span&gt;
&lt;span id="cb6-9"&gt;&lt;a href="#cb6-9"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb6-10"&gt;&lt;a href="#cb6-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-11"&gt;&lt;a href="#cb6-11"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Nil(&lt;span class="kw"&gt;type&lt;/span&gt; a Any)) Map(&lt;span class="kw"&gt;type&lt;/span&gt; b Any)(f Function(a,b)) List(b) {&lt;/span&gt;
&lt;span id="cb6-12"&gt;&lt;a href="#cb6-12"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Nil(b){}&lt;/span&gt;
&lt;span id="cb6-13"&gt;&lt;a href="#cb6-13"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb6-14"&gt;&lt;a href="#cb6-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-15"&gt;&lt;a href="#cb6-15"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Cons(&lt;span class="kw"&gt;type&lt;/span&gt; a Any)) Map(&lt;span class="kw"&gt;type&lt;/span&gt; b Any)(f Function(a,b)) List(b) {&lt;/span&gt;
&lt;span id="cb6-16"&gt;&lt;a href="#cb6-16"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Cons(b){f.Apply(xs.head), xs.tail.Map(b)(f)}&lt;/span&gt;
&lt;span id="cb6-17"&gt;&lt;a href="#cb6-17"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb6-18"&gt;&lt;a href="#cb6-18"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-19"&gt;&lt;a href="#cb6-19"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; main() {&lt;/span&gt;
&lt;span id="cb6-20"&gt;&lt;a href="#cb6-20"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; xs List(&lt;span class="dt"&gt;int&lt;/span&gt;) = Cons(&lt;span class="dt"&gt;int&lt;/span&gt;){&lt;span class="dv"&gt;3&lt;/span&gt;, Cons(&lt;span class="dt"&gt;int&lt;/span&gt;){&lt;span class="dv"&gt;6&lt;/span&gt;, Nil(&lt;span class="dt"&gt;int&lt;/span&gt;){}}}&lt;/span&gt;
&lt;span id="cb6-21"&gt;&lt;a href="#cb6-21"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; ys List(&lt;span class="dt"&gt;int&lt;/span&gt;) = xs.Map(&lt;span class="dt"&gt;int&lt;/span&gt;)(incr{-&lt;span class="dv"&gt;5&lt;/span&gt;})&lt;/span&gt;
&lt;span id="cb6-22"&gt;&lt;a href="#cb6-22"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; _ List(&lt;span class="dt"&gt;bool&lt;/span&gt;) = ys.Map(&lt;span class="dt"&gt;bool&lt;/span&gt;)(pos{})&lt;/span&gt;
&lt;span id="cb6-23"&gt;&lt;a href="#cb6-23"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;List&lt;/code&gt; インターフェースは，配列のようなコンテナ型の各要素に同じメソッドを適用する高階関数を提供する． &lt;code&gt;Nil&lt;/code&gt; と &lt;code&gt;Cons&lt;/code&gt; 構造体は線形リストを表したものだ． ちなみに，Go の構造体は構造体による再帰的な構造を宣言することはできないが，インターフェースを介する場合は可能だ．&lt;/p&gt;
&lt;p&gt;さて，これを単相化すると次のようになる．&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; main() {&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; xs List&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; = Cons&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;{&lt;span class="dv"&gt;3&lt;/span&gt;, Cons&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;{&lt;span class="dv"&gt;6&lt;/span&gt;, Nil&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;}}&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; ys List&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; = xs.Map&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;(incr{-&lt;span class="dv"&gt;5&lt;/span&gt;})&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;var&lt;/span&gt; _ List&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; = ys.Map&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;(pos{})&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="#cb7-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; List&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; &lt;span class="kw"&gt;interface&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb7-8"&gt;&lt;a href="#cb7-8"&gt;&lt;/a&gt;    Map&amp;lt;&lt;span class="dv"&gt;2&lt;/span&gt;&amp;gt;() Top &lt;span class="co"&gt;// これは `(f Function(int, b)) List(b)` からの数字&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-9"&gt;&lt;a href="#cb7-9"&gt;&lt;/a&gt;    Map&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;(f Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;,&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;) List&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span id="cb7-10"&gt;&lt;a href="#cb7-10"&gt;&lt;/a&gt;    Map&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;(f Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;,&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;) List&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span id="cb7-11"&gt;&lt;a href="#cb7-11"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-12"&gt;&lt;a href="#cb7-12"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-13"&gt;&lt;a href="#cb7-13"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Nil&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; &lt;span class="kw"&gt;struct&lt;/span&gt; {}&lt;/span&gt;
&lt;span id="cb7-14"&gt;&lt;a href="#cb7-14"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Nil&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;) Map&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;(f Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;,&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;) List&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; {&lt;/span&gt;
&lt;span id="cb7-15"&gt;&lt;a href="#cb7-15"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Nil&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;{}&lt;/span&gt;
&lt;span id="cb7-16"&gt;&lt;a href="#cb7-16"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-17"&gt;&lt;a href="#cb7-17"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Nil&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;) Map&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;(f Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;,&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;) List&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; {&lt;/span&gt;
&lt;span id="cb7-18"&gt;&lt;a href="#cb7-18"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Nil&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;{}&lt;/span&gt;
&lt;span id="cb7-19"&gt;&lt;a href="#cb7-19"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-20"&gt;&lt;a href="#cb7-20"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Nil&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;) Map&amp;lt;&lt;span class="dv"&gt;2&lt;/span&gt;&amp;gt;() Top {&lt;/span&gt;
&lt;span id="cb7-21"&gt;&lt;a href="#cb7-21"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Top{}&lt;/span&gt;
&lt;span id="cb7-22"&gt;&lt;a href="#cb7-22"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-23"&gt;&lt;a href="#cb7-23"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-24"&gt;&lt;a href="#cb7-24"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Cons&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; &lt;span class="kw"&gt;struct&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb7-25"&gt;&lt;a href="#cb7-25"&gt;&lt;/a&gt;    head &lt;span class="dt"&gt;int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-26"&gt;&lt;a href="#cb7-26"&gt;&lt;/a&gt;    tail List&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span id="cb7-27"&gt;&lt;a href="#cb7-27"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-28"&gt;&lt;a href="#cb7-28"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Cons&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;) Map&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;(f Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;,&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;) List&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; {&lt;/span&gt;
&lt;span id="cb7-29"&gt;&lt;a href="#cb7-29"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Cons&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;{f.Apply(xs.head), xs.tail.Map&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;(f)}&lt;/span&gt;
&lt;span id="cb7-30"&gt;&lt;a href="#cb7-30"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-31"&gt;&lt;a href="#cb7-31"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Cons&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;) Map&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;(f Function&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;,&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;) List&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; {&lt;/span&gt;
&lt;span id="cb7-32"&gt;&lt;a href="#cb7-32"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Cons&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;{f.Apply(xs.head), xs.tail.Map&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;(f)}&lt;/span&gt;
&lt;span id="cb7-33"&gt;&lt;a href="#cb7-33"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-34"&gt;&lt;a href="#cb7-34"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Cons&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;) Map&amp;lt;&lt;span class="dv"&gt;2&lt;/span&gt;&amp;gt;() Top {&lt;/span&gt;
&lt;span id="cb7-35"&gt;&lt;a href="#cb7-35"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Top{}&lt;/span&gt;
&lt;span id="cb7-36"&gt;&lt;a href="#cb7-36"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-37"&gt;&lt;a href="#cb7-37"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-38"&gt;&lt;a href="#cb7-38"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; List&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; &lt;span class="kw"&gt;interface&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb7-39"&gt;&lt;a href="#cb7-39"&gt;&lt;/a&gt;    Map&amp;lt;&lt;span class="dv"&gt;3&lt;/span&gt;&amp;gt;() Top&lt;/span&gt;
&lt;span id="cb7-40"&gt;&lt;a href="#cb7-40"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-41"&gt;&lt;a href="#cb7-41"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-42"&gt;&lt;a href="#cb7-42"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Nil&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; &lt;span class="kw"&gt;struct&lt;/span&gt; {}&lt;/span&gt;
&lt;span id="cb7-43"&gt;&lt;a href="#cb7-43"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Nil&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;) Map&amp;lt;&lt;span class="dv"&gt;3&lt;/span&gt;&amp;gt;() Top {&lt;/span&gt;
&lt;span id="cb7-44"&gt;&lt;a href="#cb7-44"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Top{}&lt;/span&gt;
&lt;span id="cb7-45"&gt;&lt;a href="#cb7-45"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-46"&gt;&lt;a href="#cb7-46"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-47"&gt;&lt;a href="#cb7-47"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Cons&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; &lt;span class="kw"&gt;struct&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb7-48"&gt;&lt;a href="#cb7-48"&gt;&lt;/a&gt;    head &lt;span class="dt"&gt;bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-49"&gt;&lt;a href="#cb7-49"&gt;&lt;/a&gt;    tail List&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span id="cb7-50"&gt;&lt;a href="#cb7-50"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb7-51"&gt;&lt;a href="#cb7-51"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (xs Cons&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;) Map&amp;lt;&lt;span class="dv"&gt;3&lt;/span&gt;&amp;gt;() Top {&lt;/span&gt;
&lt;span id="cb7-52"&gt;&lt;a href="#cb7-52"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; Top{}&lt;/span&gt;
&lt;span id="cb7-53"&gt;&lt;a href="#cb7-53"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;List&amp;lt;int&amp;gt;&lt;/code&gt; の &lt;code&gt;Map&lt;/code&gt; メソッドは &lt;code&gt;main&lt;/code&gt; のところで &lt;code&gt;int -&amp;gt; int&lt;/code&gt; と &lt;code&gt;int -&amp;gt; bool&lt;/code&gt; の2パターンで使われていたため，2つもインターフェースのメソッドとして宣言されている． 対して &lt;code&gt;List&amp;lt;bool&amp;gt;&lt;/code&gt; は &lt;code&gt;ys.Map&amp;lt;bool&amp;gt;(pos{})&lt;/code&gt; で生成されるものの，&lt;code&gt;Map&lt;/code&gt; メソッドを呼んでいないため，インターフェースのメソッドは1つもない． このようにインターフェースのメソッドは，実際に利用された型のものしか生成されない． これにより，メソッドの無いインターフェースが生成されることがある（正確にはダミーメソッド以外には無い，だが）． ダミーメソッドはこのような振る舞いに対して有効だ．例えば，変数 &lt;code&gt;f&lt;/code&gt; に &lt;code&gt;incr{1}&lt;/code&gt; が束縛されているときを考える． 型アサーション &lt;code&gt;f.(List&amp;lt;bool&amp;gt;)&lt;/code&gt; はダミーメソッドがあることで失敗するが，ダミーメソッドがないと成功してしまう．&lt;/p&gt;
&lt;h3 id="単相化ができない場合"&gt;単相化ができない場合&lt;/h3&gt;
&lt;p&gt;全ての型付け可能な FGG のコードが単相化可能かというとそうではない． 例えば，次のような FGG のコードは単相化できない．&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Box(&lt;span class="kw"&gt;type&lt;/span&gt; a Any) &lt;span class="kw"&gt;struct&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2"&gt;&lt;/a&gt;    value a&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3"&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (this Box(&lt;span class="kw"&gt;type&lt;/span&gt; a Any)) Nest(n &lt;span class="dt"&gt;int&lt;/span&gt;) Any {&lt;/span&gt;
&lt;span id="cb8-6"&gt;&lt;a href="#cb8-6"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; (n == &lt;span class="dv"&gt;0&lt;/span&gt;) {&lt;/span&gt;
&lt;span id="cb8-7"&gt;&lt;a href="#cb8-7"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; this&lt;/span&gt;
&lt;span id="cb8-8"&gt;&lt;a href="#cb8-8"&gt;&lt;/a&gt;    } &lt;span class="kw"&gt;else&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb8-9"&gt;&lt;a href="#cb8-9"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; Box(Box(a)){this}.Nest(n&lt;span class="dv"&gt;-1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-10"&gt;&lt;a href="#cb8-10"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb8-11"&gt;&lt;a href="#cb8-11"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは多相再帰（polymorphic recursion），ある型で呼び出されたメソッドが別の型で再帰呼び出しをするもの，をしているプログラムの例である．&lt;code&gt;Box(a)&lt;/code&gt; 型をレシーバーとするメソッド &lt;code&gt;Nest&lt;/code&gt; を呼び出すと &lt;code&gt;Box(Box(a))&lt;/code&gt; 型のレシーバーで再帰的に呼び出される． この例は型がどれだけ深くネストするかを事前に決定することができないので単相化することができない．&lt;/p&gt;
&lt;p&gt;逆に，このような多相再帰なコードが含まれていない場合は，全ての FGG のコードを単相化することができる（ことを論文で証明していた）． なので，実際のコンパイラでは多相再帰が含まれてるかどうかの検査をするようだ．&lt;/p&gt;
&lt;h3 id="単相化の仕組み"&gt;単相化の仕組み&lt;/h3&gt;
&lt;p&gt;単相化のプロセスは2つのフェーズから構成されている． 第一フェーズは，FGG プログラムから型とメソッドのインスタンス（型パラメーターを具体化したものだと思う）を取集する． 第二フェーズでは，第一フェーズで収集したインスタンスをもとにして，FGG プログラムを等価な FG プログラムへと変換する．&lt;/p&gt;
&lt;p&gt;FGG のプログラム &lt;span class="math inline"&gt;&lt;em&gt;P&lt;/em&gt;&lt;/span&gt; から，各インスタンスの集合 &lt;span class="math inline"&gt;&lt;em&gt;Ω&lt;/em&gt;&lt;/span&gt; を収集した場合は &lt;span class="math inline"&gt;&lt;em&gt;P&lt;/em&gt; ▸ &lt;em&gt;Ω&lt;/em&gt;&lt;/span&gt; と記述する（これが第一フェーズ）．FGG のプログラム &lt;span class="math inline"&gt;&lt;em&gt;P&lt;/em&gt;&lt;/span&gt; から FG のプログラム &lt;span class="math inline"&gt;&lt;em&gt;P&lt;/em&gt;′&lt;/span&gt; への変換は &lt;span class="math inline"&gt; ⊢ &lt;em&gt;P&lt;/em&gt; ↦ &lt;em&gt;P&lt;/em&gt;′&lt;/span&gt; と記述する．&lt;/p&gt;
&lt;p&gt;論文ではこれらの規則を形式的に定義している（がここでは割愛）．&lt;/p&gt;
&lt;h3 id="他言語と単相化"&gt;他言語と単相化&lt;/h3&gt;
&lt;p&gt;7章の「RELATED WORK」では，他のプログラミング言語での単相化の事例について紹介されていた．興味深いので論文から引用する．&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bracha 氏らは「Making the Future Safe for the Past: Adding Genericity to the Java Programming Language」という論文でジェネリクス付きの Java からジェネリクスなしの Java へ，全ての型パラメーターの情報を消去することで変換する方法を提案した（これは単相化では無い）．消去の欠点として消去されたコードは単相化されたコードに比べて（実行？）効率が悪くなることがよくある．一方，消去はコードサイズの増加が線形であるのに対して，単相化はコードサイズが爆発的に増加する可能性がある．&lt;/li&gt;
&lt;li&gt;Kennedy 氏と Syme 氏は「Design and Implementation of Generics for the .NET Common Language Runtime」で .NET Common Language Runtime (CLR) と C# の拡張を開発してジェネリクスをサポートした．これらは特化したコードと共有したコードを混ぜたものを生成する．前者は，各プリミティブ型ごとに個別にコンパイルする（これは単相化に似ている）．後者は，全てのオブジェクト型に対してひとつにコンパイルされる（これは消去に似ている）．&lt;/li&gt;
&lt;li&gt;Stroustrup 氏は「The C++ Programming Language」という書籍の16章で，C++ におけるテンプレートのインスタンス化について述べている（実質，単相化）．これは広く使われているがコードが肥大化するとして悪名高い．&lt;/li&gt;
&lt;li&gt;Benton 氏らは「Compiling Standard ML to Java Bytecodes」という論文で SML’97 プログラムから Java バイトコードへ変換するコンパイラについて述べており，ここで多相性は完全に単相化される．Standard ML では多相的な再帰を禁止しているため，常に単相化することが可能．&lt;/li&gt;
&lt;li&gt;Fluet 氏は &lt;a href="http://mlton.org/Monomorphise"&gt;MLton のウェブページ&lt;/a&gt;で，SML の最適化コンパイラ MLton で利用している同様のアプローチを紹介している．&lt;/li&gt;
&lt;li&gt;Tolmach 氏と Oliva 氏は「From ML to Ada: Strongly-Typed Language Interoperability via Source Translation」という論文で，MLライクな言語から Agda への型付きの変換を単相化ベースで開発し，その詳細を発表した．FGGのとは異なりサブタイピングに対応しておらず多相再帰もない．&lt;/li&gt;
&lt;li&gt;Jones 氏は「Dictionary-free overloading by partial evaluation」という論文で，Haskell用の型クラスを効率的にコンパイルする方法について述べており，これは単相化に多少似ている．&lt;/li&gt;
&lt;li&gt;Yu 氏らは「Formalization of generics for the .NET common language runtime」で，.NET JIT コンパイラの特化と共有を混ぜるメカニズムの形式化している．この論文では，型と意味論を保持した多相的な .NET の中間言語（IL）への変換を記述している．&lt;/li&gt;
&lt;li&gt;Siek 氏と Taha 氏は「A Semantic Analysis of C++ Templates」という論文で，C++テンプレートのインスタンス化メカニズムを形式化している．&lt;/li&gt;
&lt;li&gt;田中氏らは「Safe Low-level Code Generation in Coq Using Monomorphization and Monadification」という論文で，低レベルのCコードを生成する Coq (Gallina) のための単相化アルゴリズムをレポートしている．&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="実装について"&gt;実装について&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FGとFGGの型検査器とインタプリタ&lt;/li&gt;
&lt;li&gt;FGG から FG への変換器（monomorphiser）のプロトタイプ実装（単相化可能かの検査も含む）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を Go で実装して公開したそうだ． Go で実装したのは Go の設計者やコミュニティとの議論を容易にするためらしい． さらに，これらの実装を使い多くのテストを行ったようだ．&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FG の評価結果を公式の Go コンパイラを使用したものと比較&lt;/li&gt;
&lt;li&gt;FG と FGG インタプリタは保存定理と進行定理の動的な検査をサポート&lt;/li&gt;
&lt;li&gt;単相化をテストするために双模倣性のテストを追加&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;また，&lt;a href="https://doi.org/10.1017/s0956796815000143"&gt;NEAT&lt;/a&gt; を利用して FGG のサブセットから全ての正しく型付けされたプログラム（ただし，メソッドと型の出現巣の合計を指定して，ある程度のサイズまでに限定した上で）を列挙もしたらしい（SmallCheck に似ているらしい）． このサブセットに含まれる全ての FGG プログラムをサイズ20まで生成して，上述した双模倣性のテストが通ったことを確認したそうだ．&lt;/p&gt;
&lt;h2 id="おしまい"&gt;おしまい&lt;/h2&gt;
&lt;p&gt;今後は C# のような，型のランタイム表現を渡すことに基づいた実装を検討して，単相化と組み合わせる方法を模索するらしい． あと，代入・配列・スライス・パッケージなどの他の重要な機能のモデル化も計画してるらしく，これを Bantamweight Go と呼ぶつもりらしい． さらに，「goroutines」とメッセージパッシングに基づくGoの並行メカニズムのモデル化も計画していて，これを Cruiserweight Go と呼ぶらしい． いったい素の Go は何級なんだろう笑&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/07/01/224033</id><title type="text">Surface Book 3を手にするまでの2ヶ月の苦闘の記録</title><updated>2020-07-01T22:40:33+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/07/01/224033"/><summary type="html">Surface Book 2 を買ってから 2年半が経過し、今回 Surface Book 3 を購入した。日本でも販売されることを知らずに US のマイクロソフトストアで購入したのだが、今回実機を手にするまでにめちゃめちゃ苦労したので、記録を残しておく。 US キーボードが欲しかったので、まあ、苦労した意味は0ではないかなと思っている。 5/7 予約 Surface Book 2 がとても気に入っていたので、 Surface Book 3 の発表はずっと待っていた。 発表された ことを知り、即予約をした。クレジットカードの認証がうまくいかなかったり、2重で注文してしまったり（！）と言ったトラ…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2019/08/26/090000</id><title type="text">jqのGo実装 gojq を作りました！ ― スタックマシン型インタープリタによるイテレータセマンティクスの実装</title><updated>2020-06-15T14:30:25+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2019/08/26/090000"/><summary type="html">jqはとても便利なコマンドです。 JSONを返すAPIを実装するときや、SaaSのAPIから特定の情報を抜き出してシェル変数に代入するときなど、web開発や運用には欠かせないツールとなっています。 しかし、私にとってjqのクエリを一発で書くのは容易ではなく、思い通りの出力が得られないことがよくありました。 難しいエラーメッセージに悩まされて、jqで書くのを諦めて別の言語で書き直すこともありました。 jqの十八番と思える場面で使いこなせないのは、なかなか悔しいものがあります。 ツールを使うのが難しいなら、同じものを作ってしまえばよいのです。 jqの全ての機能を実装する jqを言語としてきちんと書…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2020-06-13-build-docker-image-for-hamler.html</id><title type="text">Hamler の Docker イメージを作る</title><updated>2020-06-13T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2020-06-13-build-docker-image-for-hamler.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;&lt;a href="https://www.hamler-lang.org/"&gt;Hamler&lt;/a&gt; という ErlangVM 上で動作する Haskell に似た構文のプログラミング言語が公開された． 手元で遊ぶためにまず，Docker イメージを作ってみることにした（brew したくなかった）． &lt;a href="https://hub.docker.com/repository/docker/matsubara0507/hamler"&gt;作成したイメージはココ&lt;/a&gt;で&lt;a href="https://github.com/matsubara0507/docker-hamler"&gt;リポジトリはココ&lt;/a&gt;．&lt;/p&gt;
&lt;p&gt;ちなみに，今回利用するバージョンは &lt;code&gt;0.1&lt;/code&gt; です．&lt;/p&gt;
&lt;h2 id="docker-イメージを作る"&gt;Docker イメージを作る&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/erlang/docker-erlang-otp/blob/ed3bd9400e1b72b2bdd08596990f8ed3350a75c0/22/Dockerfile#L1"&gt;公式の Erlang の Docker イメージは Debian&lt;/a&gt; なので，Debian の Docker イメージを作る． 現状は Mac 用のバイナリしか提供されていないので自前でビルドする必要がある． 自前でビルドする方法は&lt;a href="https://github.com/hamler-lang/hamler/tree/2ed8e6088721471a4dd7993eb6a984fb7ce66a73#installation"&gt;公式ドキュメント&lt;/a&gt;によると次の通り：&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;Erlang インストール&lt;/li&gt;
&lt;li&gt;Haskell Stack をインストール&lt;/li&gt;
&lt;li&gt;hamler-lang/hamler リポジトリをクローン&lt;/li&gt;
&lt;li&gt;リポジトリで &lt;code&gt;make &amp;amp;&amp;amp; make install&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;幸いにも，Hamler は Haskell Stack でビルドできるので簡単だ．&lt;/p&gt;
&lt;h3 id="コンパイラをビルドする"&gt;コンパイラをビルドする&lt;/h3&gt;
&lt;p&gt;まずは Stack をインストールしよう：&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode dockerfile"&gt;&lt;code class="sourceCode dockerfile"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# マルチステージビルドをするので AS でタグづけしておく&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;ARG&lt;/span&gt; OTP_VERSION=22.3.4.1&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;FROM&lt;/span&gt; erlang:${OTP_VERSION} AS build&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;WORKDIR&lt;/span&gt; /work&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;RUN&lt;/span&gt; curl -sSL https://get.haskellstack.org/ | sh&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;次にリポジトリを &lt;code&gt;git clone&lt;/code&gt; してビルドする：&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode dockerfile"&gt;&lt;code class="sourceCode dockerfile"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;ARG&lt;/span&gt; HAMLER_VERSION=0.1&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;RUN&lt;/span&gt; git clone --branch=v$HAMLER_VERSION --depth=1 https://github.com/hamler-lang/hamler.git&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;RUN&lt;/span&gt; cd hamler &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;で，&lt;code&gt;make&lt;/code&gt; というか中身は &lt;code&gt;stack build&lt;/code&gt; のところで次のようなエラーが出た：&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Package&lt;/span&gt; index cache populated&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Cloning&lt;/span&gt; afb0b731ff457d278403ab4bc134d3c88e09ea1f from git@github.com:hamler-lang/CoreErlang.git&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Received&lt;/span&gt; ExitFailure 128 when running&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Raw&lt;/span&gt; command: /usr/bin/git clone git@github.com:hamler-lang/CoreErlang.git /tmp/with-repo10/cloned&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Standard&lt;/span&gt; error:&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Cloning&lt;/span&gt; into &lt;span class="st"&gt;&amp;#39;/tmp/with-repo10/cloned&amp;#39;&lt;/span&gt;...&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Host&lt;/span&gt; key verification failed.&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9"&gt;&lt;/a&gt;&lt;span class="ex"&gt;fatal&lt;/span&gt;: Could not read from remote repository.&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Please&lt;/span&gt; make sure you have the correct access rights&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12"&gt;&lt;/a&gt;&lt;span class="ex"&gt;and&lt;/span&gt; the repository exists.&lt;/span&gt;
&lt;span id="cb3-13"&gt;&lt;a href="#cb3-13"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-14"&gt;&lt;a href="#cb3-14"&gt;&lt;/a&gt;&lt;span class="ex"&gt;make&lt;/span&gt;: *** [Makefile:9: build] Error 1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは stack.yaml の &lt;code&gt;extra-deps&lt;/code&gt; で次のように指定していたからだ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode yaml"&gt;&lt;code class="sourceCode yaml"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;-&lt;/span&gt;&lt;span class="at"&gt; &lt;/span&gt;&lt;span class="fu"&gt;git&lt;/span&gt;&lt;span class="kw"&gt;:&lt;/span&gt;&lt;span class="at"&gt; git@github.com:hamler-lang/CoreErlang.git&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2"&gt;&lt;/a&gt;&lt;span class="at"&gt;  &lt;/span&gt;&lt;span class="fu"&gt;commit&lt;/span&gt;&lt;span class="kw"&gt;:&lt;/span&gt;&lt;span class="at"&gt; afb0b731ff457d278403ab4bc134d3c88e09ea1f&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;-&lt;/span&gt;&lt;span class="at"&gt; &lt;/span&gt;&lt;span class="fu"&gt;git&lt;/span&gt;&lt;span class="kw"&gt;:&lt;/span&gt;&lt;span class="at"&gt; git@github.com:hamler-lang/purescript.git&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4"&gt;&lt;/a&gt;&lt;span class="at"&gt;  &lt;/span&gt;&lt;span class="fu"&gt;commit&lt;/span&gt;&lt;span class="kw"&gt;:&lt;/span&gt;&lt;span class="at"&gt; 2c43709229b12e72dfc550ccf3efce6bfa60da72&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;git@github.com:owner/repo.git&lt;/code&gt; という形で指定すると SSH を利用した方法で &lt;code&gt;git clone&lt;/code&gt; をするのだが，この Docker 環境では SSH の設定をしていないのでエラーになる． なので，次のように書き換えてあげれば良い：&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode yaml"&gt;&lt;code class="sourceCode yaml"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;-&lt;/span&gt;&lt;span class="at"&gt; &lt;/span&gt;&lt;span class="fu"&gt;github&lt;/span&gt;&lt;span class="kw"&gt;:&lt;/span&gt;&lt;span class="at"&gt; hamler-lang/CoreErlang&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2"&gt;&lt;/a&gt;&lt;span class="at"&gt;  &lt;/span&gt;&lt;span class="fu"&gt;commit&lt;/span&gt;&lt;span class="kw"&gt;:&lt;/span&gt;&lt;span class="at"&gt; afb0b731ff457d278403ab4bc134d3c88e09ea1f&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;-&lt;/span&gt;&lt;span class="at"&gt; &lt;/span&gt;&lt;span class="fu"&gt;github&lt;/span&gt;&lt;span class="kw"&gt;:&lt;/span&gt;&lt;span class="at"&gt; hamler-lang/purescript&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4"&gt;&lt;/a&gt;&lt;span class="at"&gt;  &lt;/span&gt;&lt;span class="fu"&gt;commit&lt;/span&gt;&lt;span class="kw"&gt;:&lt;/span&gt;&lt;span class="at"&gt; 2c43709229b12e72dfc550ccf3efce6bfa60da72&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このように修正した &lt;code&gt;stack.yaml&lt;/code&gt; を用意して上書きすることにした：&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode dockerfile"&gt;&lt;code class="sourceCode dockerfile"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;ARG&lt;/span&gt; HAMLER_VERSION=0.1&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;RUN&lt;/span&gt; git clone --branch=v$HAMLER_VERSION --depth=1 https://github.com/hamler-lang/hamler.git&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;COPY&lt;/span&gt; stack.yaml hamler/stack.yaml&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;RUN&lt;/span&gt; cd hamler &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;余談だが，これについては&lt;a href="https://github.com/hamler-lang/hamler/pull/157"&gt;修正PRを出してマージされた&lt;/a&gt;ので次のバージョンからは必要ない． で，今度は次のようなエラーが出た：&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;language-javascript&lt;/span&gt;              &lt;span class="op"&gt;&amp;gt;&lt;/span&gt; configure&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2"&gt;&lt;/a&gt;&lt;span class="ex"&gt;language-javascript&lt;/span&gt;              &lt;span class="op"&gt;&amp;gt;&lt;/span&gt; Configuring language-javascript-0.7.0.0...&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3"&gt;&lt;/a&gt;&lt;span class="ex"&gt;language-javascript&lt;/span&gt;              &lt;span class="op"&gt;&amp;gt;&lt;/span&gt; build&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4"&gt;&lt;/a&gt;&lt;span class="ex"&gt;language-javascript&lt;/span&gt;              &lt;span class="op"&gt;&amp;gt;&lt;/span&gt; Preprocessing library for language-javascript-0.7.0.0..&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5"&gt;&lt;/a&gt;&lt;span class="ex"&gt;language-javascript&lt;/span&gt;              &lt;span class="op"&gt;&amp;gt;&lt;/span&gt; happy: src/Language/JavaScript/Parser/Grammar7.y: hGetContents: invalid argument (invalid byte sequence)&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6"&gt;&lt;/a&gt;&lt;span class="ex"&gt;--&lt;/span&gt;  While building package language-javascript-0.7.0.0 using:&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="#cb7-7"&gt;&lt;/a&gt;      &lt;span class="ex"&gt;/root/.stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_2.4.0.1_ghc-8.6.5&lt;/span&gt; --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-2.4.0.1 build --ghc-options &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-8"&gt;&lt;a href="#cb7-8"&gt;&lt;/a&gt;    &lt;span class="ex"&gt;Process&lt;/span&gt; exited with code: ExitFailure 1&lt;/span&gt;
&lt;span id="cb7-9"&gt;&lt;a href="#cb7-9"&gt;&lt;/a&gt;&lt;span class="ex"&gt;make&lt;/span&gt;: *** [Makefile:9: build] Error 1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;はい，親の顔よりも見る &lt;code&gt;hGetContents: invalid argument (invalid byte sequence)&lt;/code&gt; ですね． language-javascript パッケージは UTF-8 前提なので &lt;code&gt;LC_ALL&lt;/code&gt; 環境変数を UTF-8 にしてあげる必要がある：&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode dockerfile"&gt;&lt;code class="sourceCode dockerfile"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;ARG&lt;/span&gt; HAMLER_VERSION=0.1&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;RUN&lt;/span&gt; git clone --branch=v$HAMLER_VERSION --depth=1 https://github.com/hamler-lang/hamler.git&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;COPY&lt;/span&gt; stack.yaml hamler/stack.yaml&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;ENV&lt;/span&gt; LC_ALL C.UTF-8&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;RUN&lt;/span&gt; cd hamler &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これでコンパイラのビルドは成功した！&lt;/p&gt;
&lt;h3 id="replを試すまで"&gt;REPLを試すまで&lt;/h3&gt;
&lt;p&gt;マルチステージビルドなのでビルドしたコンパイラを次のステージにコピーしよう：&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode dockerfile"&gt;&lt;code class="sourceCode dockerfile"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;FROM&lt;/span&gt; erlang:${OTP_VERSION}&lt;/span&gt;
&lt;span id="cb9-2"&gt;&lt;a href="#cb9-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;COPY&lt;/span&gt; --from=build /root/.local/bin/hamler /usr/local/bin/hamler&lt;/span&gt;
&lt;span id="cb9-3"&gt;&lt;a href="#cb9-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;ENTRYPOINT&lt;/span&gt; [&lt;span class="st"&gt;&amp;quot;/usr/local/bin/hamler&amp;quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;試しに &lt;code&gt;--help&lt;/code&gt; をしてみる：&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1"&gt;&lt;/a&gt;$ &lt;span class="ex"&gt;docker&lt;/span&gt; run --rm matsubara0507/hamler --help&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Usage&lt;/span&gt;: hamler COMMAND&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="#cb10-3"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;The&lt;/span&gt; hamler compiler based on purescript v0.13.6&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="#cb10-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="#cb10-5"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Available&lt;/span&gt; options:&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="#cb10-6"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;--version&lt;/span&gt;                Show the version number&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="#cb10-7"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;-h&lt;/span&gt;,--help                Show this help text&lt;/span&gt;
&lt;span id="cb10-8"&gt;&lt;a href="#cb10-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-9"&gt;&lt;a href="#cb10-9"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Available&lt;/span&gt; commands:&lt;/span&gt;
&lt;span id="cb10-10"&gt;&lt;a href="#cb10-10"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;build&lt;/span&gt;                    Compile hamler source files&lt;/span&gt;
&lt;span id="cb10-11"&gt;&lt;a href="#cb10-11"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;init&lt;/span&gt;                     init a hamler project&lt;/span&gt;
&lt;span id="cb10-12"&gt;&lt;a href="#cb10-12"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;run&lt;/span&gt;                      run hamler project&lt;/span&gt;
&lt;span id="cb10-13"&gt;&lt;a href="#cb10-13"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;repldev&lt;/span&gt;                  dev hamler lib&lt;/span&gt;
&lt;span id="cb10-14"&gt;&lt;a href="#cb10-14"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;repl&lt;/span&gt;                     run hamler repl&lt;/span&gt;
&lt;span id="cb10-15"&gt;&lt;a href="#cb10-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-16"&gt;&lt;a href="#cb10-16"&gt;&lt;/a&gt;&lt;span class="ex"&gt;For&lt;/span&gt; help using each individual command, run &lt;span class="kw"&gt;`&lt;/span&gt;&lt;span class="ex"&gt;hamler&lt;/span&gt; COMMAND --help&lt;span class="kw"&gt;`&lt;/span&gt;. For&lt;/span&gt;
&lt;span id="cb10-17"&gt;&lt;a href="#cb10-17"&gt;&lt;/a&gt;&lt;span class="ex"&gt;example&lt;/span&gt;, &lt;span class="kw"&gt;`&lt;/span&gt;&lt;span class="ex"&gt;hamler&lt;/span&gt; build --help&lt;span class="kw"&gt;`&lt;/span&gt; displays options specific to the &lt;span class="kw"&gt;`&lt;/span&gt;&lt;span class="ex"&gt;build&lt;/span&gt;&lt;span class="kw"&gt;`&lt;/span&gt; command.&lt;/span&gt;
&lt;span id="cb10-18"&gt;&lt;a href="#cb10-18"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-19"&gt;&lt;a href="#cb10-19"&gt;&lt;/a&gt;&lt;span class="ex"&gt;hamler&lt;/span&gt; 0.1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;動作確認するために REPL を試してみる：&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1"&gt;&lt;/a&gt;$ &lt;span class="ex"&gt;docker&lt;/span&gt; run -it --rm matsubara0507/hamler repl&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2"&gt;&lt;/a&gt;&lt;span class="ex"&gt;hamler&lt;/span&gt;: //src: getDirectoryContents:openDirStream: does not exist (No such file or directory)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;グローバルな環境で REPL は使えないっぽいのでプロジェクトを作成してみる：&lt;/p&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb12-1"&gt;&lt;a href="#cb12-1"&gt;&lt;/a&gt;$ &lt;span class="ex"&gt;docker&lt;/span&gt; run --rm -w /work -v &lt;span class="kw"&gt;`&lt;/span&gt;&lt;span class="bu"&gt;pwd&lt;/span&gt;&lt;span class="kw"&gt;`&lt;/span&gt;/example:/work matsubara0507/hamler init&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="#cb12-2"&gt;&lt;/a&gt;$ &lt;span class="ex"&gt;docker&lt;/span&gt; run -it --rm -w /work -v &lt;span class="kw"&gt;`&lt;/span&gt;&lt;span class="bu"&gt;pwd&lt;/span&gt;&lt;span class="kw"&gt;`&lt;/span&gt;/example:/work matsubara0507/hamler repl&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="#cb12-3"&gt;&lt;/a&gt;&lt;span class="ex"&gt;hamler&lt;/span&gt;: /usr/local/lib/hamler/lib: getDirectoryContents:openDirStream: does not exist (No such file or directory)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;/usr/local/lib/hamler/lib&lt;/code&gt; ？？？ いったいこれはどこで参照してるやつだ？？？と思ってリポジトリで色々調べてみたところ，どうやら標準ライブラリかなんかを参照してるっぽい． バグかな？って思ったけど &lt;a href="https://github.com/hamler-lang/homebrew-hamler/blob/0.1/Formula/hamler.rb#L38-L40"&gt;&lt;code&gt;brew&lt;/code&gt; の設定&lt;/a&gt;をみてみたらリポジトリっぽいのを &lt;code&gt;/usr/local/lib/hamler&lt;/code&gt; にシンボリックリンクしてるようだった． なので，試しにそうしてみる：&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode dockerfile"&gt;&lt;code class="sourceCode dockerfile"&gt;&lt;span id="cb13-1"&gt;&lt;a href="#cb13-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;FROM&lt;/span&gt; erlang:${OTP_VERSION}&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="#cb13-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;COPY&lt;/span&gt; --from=build /root/.local/bin/hamler /usr/local/bin/hamler&lt;/span&gt;
&lt;span id="cb13-3"&gt;&lt;a href="#cb13-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;COPY&lt;/span&gt; --from=build /work/hamler /usr/local/lib/hamler&lt;/span&gt;
&lt;span id="cb13-4"&gt;&lt;a href="#cb13-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;ENTRYPOINT&lt;/span&gt; [&lt;span class="st"&gt;&amp;quot;/usr/local/bin/hamler&amp;quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;今度はこういうエラーが出た：&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode dockerfile"&gt;&lt;code class="sourceCode dockerfile"&gt;&lt;span id="cb14-1"&gt;&lt;a href="#cb14-1"&gt;&lt;/a&gt;$ docker run -it --rm -w /work -v `pwd`/example:/work matsubara0507/hamler repl&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="#cb14-2"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;quot;/work&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="#cb14-3"&gt;&lt;/a&gt;hamler: /usr/local/lib/hamler/bin/replsrv: start replsrv error!! : runInteractiveProcess: exec: does not exist (No such file or directory)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;bin/replsrv&lt;/code&gt; ？？？ &lt;code&gt;brew&lt;/code&gt; でインストールしてる tgz の中身をみてみたら &lt;code&gt;bin&lt;/code&gt; ディレクトリがあり，そこには &lt;code&gt;replsrv&lt;/code&gt; と &lt;code&gt;hamler&lt;/code&gt; というファイルがあった． &lt;code&gt;hamler&lt;/code&gt; はコンパイラのバイナリで，&lt;code&gt;replsrv&lt;/code&gt; は Erlang のスクリプトだった． 探してみたら &lt;code&gt;repl/replsrv&lt;/code&gt; という Erlang スクリプトがリポジトリにあり，&lt;code&gt;diff&lt;/code&gt; してみたら tgz のものと一緒だった． なのでこれをコピーするようにした：&lt;/p&gt;
&lt;div class="sourceCode" id="cb15"&gt;&lt;pre class="sourceCode dockerfile"&gt;&lt;code class="sourceCode dockerfile"&gt;&lt;span id="cb15-1"&gt;&lt;a href="#cb15-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;FROM&lt;/span&gt; erlang:${OTP_VERSION}&lt;/span&gt;
&lt;span id="cb15-2"&gt;&lt;a href="#cb15-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;COPY&lt;/span&gt; --from=build /root/.local/bin/hamler /usr/local/bin/hamler&lt;/span&gt;
&lt;span id="cb15-3"&gt;&lt;a href="#cb15-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;COPY&lt;/span&gt; --from=build /work/hamler /usr/local/lib/hamler&lt;/span&gt;
&lt;span id="cb15-4"&gt;&lt;a href="#cb15-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;RUN&lt;/span&gt; mkdir /usr/local/lib/hamler/bin \&lt;/span&gt;
&lt;span id="cb15-5"&gt;&lt;a href="#cb15-5"&gt;&lt;/a&gt; &amp;amp;&amp;amp; cp /usr/local/lib/hamler/repl/replsrv /usr/local/lib/hamler/bin&lt;/span&gt;
&lt;span id="cb15-6"&gt;&lt;a href="#cb15-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;ENTRYPOINT&lt;/span&gt; [&lt;span class="st"&gt;&amp;quot;/usr/local/bin/hamler&amp;quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;なんとこれで REPL が動作した：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run -it --rm -w /work -v `pwd`/example:/work matsubara0507/hamler repl
&amp;quot;/work&amp;quot;
Compiling Data.Void
...
Compiling Main
Compiling Demo.GenServer
PSCi, version 0.13.6
Type :? for help

&amp;gt; :?
The following commands are available:

    :?                        Show this help menu
    :quit                     Quit PSCi
    :reload                   Reload all imported modules while discarding bindings
    :clear                    Discard all imported modules and declared bindings
    :browse      &amp;lt;module&amp;gt;     See all functions in &amp;lt;module&amp;gt;
    :type        &amp;lt;expr&amp;gt;       Show the type of &amp;lt;expr&amp;gt;
    :kind        &amp;lt;type&amp;gt;       Show the kind of &amp;lt;type&amp;gt;
    :show        import       Show all imported modules
    :show        loaded       Show all loaded modules
    :show        print        Show the repl&amp;#39;s current printing function
    :paste       paste        Enter multiple lines, terminated by ^D
    :complete    &amp;lt;prefix&amp;gt;     Show completions for &amp;lt;prefix&amp;gt; as if pressing tab
    :print       &amp;lt;fn&amp;gt;         Set the repl&amp;#39;s printing function to &amp;lt;fn&amp;gt; (which must be fully qualified)
    :set         pro val      Set the pro&amp;#39;s val

Further information is available on the PureScript documentation repository:
 --&amp;gt; https://github.com/purescript/documentation/blob/master/guides/PSCi.md
&amp;gt; 1 + 1
2
&amp;gt; :type 1
Integer&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;やったね．&lt;/p&gt;
&lt;h2 id="おまけサンプルプログラム"&gt;おまけ：サンプルプログラム&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/hamler-lang/documentation/blob/60607565253a2b6fa3984067cf068c20ec971d69/guides/01_WhyHamler.md#erlang-and-concurrency"&gt;ここにあるサンプルプログラム&lt;/a&gt;をビルドして実行してみた：&lt;/p&gt;
&lt;div class="sourceCode" id="cb17"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb17-1"&gt;&lt;a href="#cb17-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- `hamler run` は Main.main 関数を実行するみたい&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-2"&gt;&lt;a href="#cb17-2"&gt;&lt;/a&gt;&lt;span class="ot"&gt;main ::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb17-3"&gt;&lt;a href="#cb17-3"&gt;&lt;/a&gt;main &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-4"&gt;&lt;a href="#cb17-4"&gt;&lt;/a&gt;  &lt;span class="co"&gt;-- メインプロセスのプロセスIDを取得&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-5"&gt;&lt;a href="#cb17-5"&gt;&lt;/a&gt;  pid0 &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; selfPid&lt;/span&gt;
&lt;span id="cb17-6"&gt;&lt;a href="#cb17-6"&gt;&lt;/a&gt;  &lt;span class="co"&gt;-- `spawn` は子プロセスの生成、`seqio` は IO 専用の `sequence`&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-7"&gt;&lt;a href="#cb17-7"&gt;&lt;/a&gt;  pid100 &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; seqio [spawn loop (&lt;span class="dt"&gt;State&lt;/span&gt; pid0) &lt;span class="op"&gt;|&lt;/span&gt; x &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; [&lt;span class="dv"&gt;1&lt;/span&gt;&lt;span class="op"&gt;..&lt;/span&gt;&lt;span class="dv"&gt;1000&lt;/span&gt;]]&lt;/span&gt;
&lt;span id="cb17-8"&gt;&lt;a href="#cb17-8"&gt;&lt;/a&gt;  &lt;span class="co"&gt;-- `last` はリストの最後の要素を、`init` はリストの最後以外の部分リストを返す&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-9"&gt;&lt;a href="#cb17-9"&gt;&lt;/a&gt;  &lt;span class="co"&gt;-- `[x|xs]` は Haskell の `x:xs`、つまりリストの中身を1つずらしてる&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-10"&gt;&lt;a href="#cb17-10"&gt;&lt;/a&gt;  &lt;span class="co"&gt;-- `send` は指定したプロセスにメッセージを送信する&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-11"&gt;&lt;a href="#cb17-11"&gt;&lt;/a&gt;  seqio [send j (&lt;span class="dt"&gt;Next&lt;/span&gt; i) &lt;span class="op"&gt;|&lt;/span&gt; (i,j) &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; (&lt;span class="fu"&gt;zip&lt;/span&gt; pid100 [&lt;span class="fu"&gt;last&lt;/span&gt; pid100&lt;span class="op"&gt;|&lt;/span&gt;&lt;span class="fu"&gt;init&lt;/span&gt; pid100]) ]&lt;/span&gt;
&lt;span id="cb17-12"&gt;&lt;a href="#cb17-12"&gt;&lt;/a&gt;  send (&lt;span class="fu"&gt;head&lt;/span&gt; pid100) (&lt;span class="dt"&gt;Trans&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;great hamler! &amp;quot;&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb17-13"&gt;&lt;a href="#cb17-13"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb17-14"&gt;&lt;a href="#cb17-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-15"&gt;&lt;a href="#cb17-15"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Message&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Next&lt;/span&gt; &lt;span class="dt"&gt;Pid&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Trans&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="dt"&gt;Integer&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-16"&gt;&lt;a href="#cb17-16"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;State&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;State&lt;/span&gt; &lt;span class="dt"&gt;Pid&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-17"&gt;&lt;a href="#cb17-17"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-18"&gt;&lt;a href="#cb17-18"&gt;&lt;/a&gt;&lt;span class="ot"&gt;dealMessage ::&lt;/span&gt; &lt;span class="dt"&gt;State&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="dt"&gt;Message&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; &lt;span class="dt"&gt;State&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-19"&gt;&lt;a href="#cb17-19"&gt;&lt;/a&gt;dealMessage (&lt;span class="dt"&gt;State&lt;/span&gt; pid) (&lt;span class="dt"&gt;Next&lt;/span&gt; p) &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;return&lt;/span&gt; (&lt;span class="dt"&gt;State&lt;/span&gt; p)&lt;/span&gt;
&lt;span id="cb17-20"&gt;&lt;a href="#cb17-20"&gt;&lt;/a&gt;dealMessage (&lt;span class="dt"&gt;State&lt;/span&gt; pid) (&lt;span class="dt"&gt;Trans&lt;/span&gt; str &lt;span class="dv"&gt;11111&lt;/span&gt;) &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;return&lt;/span&gt; (&lt;span class="dt"&gt;State&lt;/span&gt; pid)&lt;/span&gt;
&lt;span id="cb17-21"&gt;&lt;a href="#cb17-21"&gt;&lt;/a&gt;dealMessage (&lt;span class="dt"&gt;State&lt;/span&gt; pid) (&lt;span class="dt"&gt;Trans&lt;/span&gt; str i) &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-22"&gt;&lt;a href="#cb17-22"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;do&lt;/span&gt; send pid (&lt;span class="dt"&gt;Trans&lt;/span&gt; str (i&lt;span class="op"&gt;+&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb17-23"&gt;&lt;a href="#cb17-23"&gt;&lt;/a&gt;     pid0 &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; selfPid&lt;/span&gt;
&lt;span id="cb17-24"&gt;&lt;a href="#cb17-24"&gt;&lt;/a&gt;     println (&lt;span class="fu"&gt;show&lt;/span&gt; pid0 &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; -&amp;gt; &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; pid &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;: &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; str &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; i)&lt;/span&gt;
&lt;span id="cb17-25"&gt;&lt;a href="#cb17-25"&gt;&lt;/a&gt;     &lt;span class="fu"&gt;return&lt;/span&gt; (&lt;span class="dt"&gt;State&lt;/span&gt; pid)&lt;/span&gt;
&lt;span id="cb17-26"&gt;&lt;a href="#cb17-26"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-27"&gt;&lt;a href="#cb17-27"&gt;&lt;/a&gt;&lt;span class="ot"&gt;loop ::&lt;/span&gt; &lt;span class="dt"&gt;State&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb17-28"&gt;&lt;a href="#cb17-28"&gt;&lt;/a&gt;loop s &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-29"&gt;&lt;a href="#cb17-29"&gt;&lt;/a&gt;  &lt;span class="co"&gt;-- `receive` は送信されたメッセージを受信する&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-30"&gt;&lt;a href="#cb17-30"&gt;&lt;/a&gt;  x &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; receive&lt;/span&gt;
&lt;span id="cb17-31"&gt;&lt;a href="#cb17-31"&gt;&lt;/a&gt;  s1 &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; dealMessage s x&lt;/span&gt;
&lt;span id="cb17-32"&gt;&lt;a href="#cb17-32"&gt;&lt;/a&gt;  loop s1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Erlang についてはあんまり詳しくないんだが，確かいわゆるアクターモデル的な並行システムだった気がする． 各 Erlang プロセスはメッセージボックス的なのを持っていて，別プロセスから送信することができる． この型検査ってどれぐらいできるのだろうか． さすがに送信・受信の型があってるかまではチェックできなそう（調べてない）．&lt;/p&gt;
&lt;p&gt;で，これをビルドした結果がこちら：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run -it --rm -w /work -v `pwd`/example:/work matsubara0507/hamler build
Compiling Data.Void
...
Compiling Demo.GenServer
Compiling Main

$ docker run -it --rm -w /work -v `pwd`/example:/work matsubara0507/hamler run
&amp;lt;0.749.0&amp;gt; -&amp;gt; &amp;lt;0.750.0&amp;gt;: great hamler! 672
&amp;lt;0.80.0&amp;gt; -&amp;gt; &amp;lt;0.81.0&amp;gt;: great hamler! 3
&amp;lt;0.81.0&amp;gt; -&amp;gt; &amp;lt;0.82.0&amp;gt;: great hamler! 4
&amp;lt;0.82.0&amp;gt; -&amp;gt; &amp;lt;0.83.0&amp;gt;: great hamler! 5
...
&amp;lt;0.791.0&amp;gt; -&amp;gt; &amp;lt;0.792.0&amp;gt;: great hamler! 7714
&amp;lt;0.792.0&amp;gt; -&amp;gt; &amp;lt;0.793.0&amp;gt;: great hamler! 7715&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="おしまい"&gt;おしまい&lt;/h2&gt;
&lt;p&gt;会社単位で作ってるみたい． すごいなぁ，羨ましい．&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/06/06/Haskell_%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%83%84%E3%83%BC%E3%83%AB%E3%83%95%E3%83%AD%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%82%92%E4%BD%9C%E3%82%8A%E3%81%BE%E3%81%97%E3%81%9F</id><title type="text">Haskell 環境構築ツールフローチャートを作りました</title><updated>2020-06-06T12:24:04+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/06/06/Haskell_%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%83%84%E3%83%BC%E3%83%AB%E3%83%95%E3%83%AD%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%82%92%E4%BD%9C%E3%82%8A%E3%81%BE%E3%81%97%E3%81%9F"/><summary type="html">前に環境構築についての記事を書いたのですが、初学者向けにパッと見て分かるようにフローチャートにしました。kakkun61.hatenablog.comGoogle ドライブ 図形描画のファイルはこちらです。コメントを付けることができます。docs.google.com</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2019/07/30/112634</id><title type="text">CloudNative Days Tokyo 2019 登壇こぼれ話 #CNDT2019</title><updated>2020-05-31T02:56:39+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2019/07/30/112634"/><summary type="html">先日行われた CloudNative Days Tokyo 2019 で、Kubernetes のスケジューリングについて発表してきました。公募 CFP 枠です。 www.youtube.com 今回の発表は、実は技術的に目新しい内容をほとんど含んでいません。各トピックは今までいくつかの勉強会で LT として発表しているものがほとんどです。 ただし、普段の発表では時間が短いこともあって断片的になりがちだった内容を 40 分の枠で再構成し、スケジューリングについて初めて聞く人にとっても入り口のギャップを少なく、できるだけ学習曲線がなだらかになるようにすることを念頭に置いてプレゼンを組み立てました…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2020-05-31-create-deps-sensor-part1.html</id><title type="text">自分の Haskell プロジェクトの依存パッケージの古さを可視化する（その１）</title><updated>2020-05-31T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2020-05-31-create-deps-sensor-part1.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;思いついたツールを自作続けるとこうなりますよね&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/create-deps-sensor/myprojects.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;時々思いつきで依存パッケージ，Stack プロジェクトであれば resolver をあげるんですけど，いい加減調べるのが大変． と言うことで，どれがどんだけ古くなってるかを可視化するツールを作りました． リポジトリはこちら：&lt;/p&gt;
&lt;h1 id="section"&gt;&lt;iframe width="320" height="163" scrolling="no" frameborder="0" src="https://matsubara0507.github.io/my-github-cards/?target=matsubara0507/repomoving"&gt;&lt;/iframe&gt;&lt;/h1&gt;
&lt;h2 id="ゴール"&gt;ゴール&lt;/h2&gt;
&lt;p&gt;今回は&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;集めるのは Haskell Stack プロジェクトのみ&lt;/li&gt;
&lt;li&gt;一覧化するのは stack.yaml に書いてる resolver のみ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;だけにする． 気が向いたときに少しずつパワーアップしていく．&lt;/p&gt;
&lt;h3 id="どうやるか"&gt;どうやるか&lt;/h3&gt;
&lt;p&gt;可視化したいプロジェクトは設定ファイルで指定する形式にする． 自動で集めても良いが，まぁそれはおいおい．&lt;/p&gt;
&lt;p&gt;で，設定をもとにルートにある &lt;code&gt;stack.yaml&lt;/code&gt; ファイルを &lt;a href="https://developer.github.com/v3/repos/contents/#get-contents"&gt;GitHub API の get-content&lt;/a&gt; を使って取得する． そのファイルを読み込んで YAML をパースして，&lt;code&gt;resolver&lt;/code&gt; あるいは &lt;code&gt;snapshot&lt;/code&gt; を出力する． それだけ．&lt;/p&gt;
&lt;p&gt;これを CLI ツールとして作る．&lt;/p&gt;
&lt;h2 id="作る"&gt;作る&lt;/h2&gt;
&lt;p&gt;まずは CLI から．&lt;/p&gt;
&lt;h3 id="cli-ツールの雛形"&gt;CLI ツールの雛形&lt;/h3&gt;
&lt;p&gt;なんと，すでに stack template を用意してあるので簡単：&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt;$ &lt;span class="ex"&gt;stack&lt;/span&gt; new deps-sensor github:matsubara0507/mix-cli.hsfiles&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このテンプレートは自作フレームワーク &lt;a href="https://github.com/matsubara0507/mix.hs"&gt;mix.hs&lt;/a&gt; を使った CLI ツールのもの． mix.hs は &lt;a href="https://github.com/fumieval/extensible"&gt;extensible パッケージ&lt;/a&gt;と &lt;a href="https://github.com/commercialhaskell/rio"&gt;rio パッケージ&lt;/a&gt;を混ぜたような簡単なフレームワークです． で，あとはよしなにモジュール名を整えたら&lt;a href="https://github.com/matsubara0507/deps-sensor/commit/f6e463f4cdd7a8488fef57364e5aedcd9ba3049b"&gt;出来上がり&lt;/a&gt;：&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;$ &lt;span class="ex"&gt;stack&lt;/span&gt; build&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;&lt;span class="ex"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;$ &lt;span class="ex"&gt;stack&lt;/span&gt; exec -- deps-sensor --help&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4"&gt;&lt;/a&gt;&lt;span class="ex"&gt;deps-sensor&lt;/span&gt; [options] [input-file]&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;-h&lt;/span&gt;  --help     Show this help text&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6"&gt;&lt;/a&gt;      &lt;span class="ex"&gt;--version&lt;/span&gt;  Show version&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7"&gt;&lt;/a&gt;  &lt;span class="ex"&gt;-v&lt;/span&gt;  --verbose  Enable verbose mode: verbosity level &lt;span class="st"&gt;&amp;quot;debug&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8"&gt;&lt;/a&gt;$ &lt;span class="ex"&gt;stack&lt;/span&gt; exec -- deps-sensor --version&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Version&lt;/span&gt; 0.1.0, Git revision Sat May 23 14:58:54 2020 +0900 (2 commits)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="設定ファイルを読み取る"&gt;設定ファイルを読み取る&lt;/h3&gt;
&lt;p&gt;まずは型を定義する． 色々考えた結果とりあえず今回はシンプルに：&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;DepsSensor.Config&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt;           &lt;span class="dt"&gt;RIO&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt;           &lt;span class="dt"&gt;Data.Extensible&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.Yaml&lt;/span&gt;       &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;Y&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Config&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Record&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8"&gt;&lt;/a&gt;  &amp;#39;[ &lt;span class="st"&gt;&amp;quot;repositories&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; [&lt;span class="dt"&gt;Text&lt;/span&gt;] &lt;span class="co"&gt;-- expect owner/name&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9"&gt;&lt;/a&gt;   ]&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11"&gt;&lt;/a&gt;&lt;span class="ot"&gt;readConfig ::&lt;/span&gt; &lt;span class="dt"&gt;MonadIO&lt;/span&gt; m &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; m &lt;span class="dt"&gt;Config&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12"&gt;&lt;/a&gt;readConfig &lt;span class="ot"&gt;=&lt;/span&gt; Y.decodeFileThrow&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;readConfig&lt;/code&gt; を定義してるのは，&lt;code&gt;Y.decodeFileThrow&lt;/code&gt; を使うときに型注釈をしなくて良くするため． この設定型を RIO の &lt;code&gt;Env&lt;/code&gt; 型に追加する：&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;DepsSensor.Env&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt;           &lt;span class="dt"&gt;RIO&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt;           &lt;span class="dt"&gt;Data.Extensible&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-5"&gt;&lt;a href="#cb4-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt;           &lt;span class="dt"&gt;DepsSensor.Config&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-6"&gt;&lt;a href="#cb4-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-7"&gt;&lt;a href="#cb4-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Record&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-8"&gt;&lt;a href="#cb4-8"&gt;&lt;/a&gt;  &amp;#39;[ &lt;span class="st"&gt;&amp;quot;logger&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;LogFunc&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-9"&gt;&lt;a href="#cb4-9"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;config&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Config&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-10"&gt;&lt;a href="#cb4-10"&gt;&lt;/a&gt;   ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;あとは CLI 側に追加するだけ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Main&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2"&gt;&lt;/a&gt;&lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4"&gt;&lt;/a&gt;&lt;span class="ot"&gt;main ::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5"&gt;&lt;/a&gt;main &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- runCmd を呼び出す&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- FilePath は CLI のコマンドライン引数で渡す&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8"&gt;&lt;/a&gt;&lt;span class="ot"&gt;runCmd ::&lt;/span&gt; &lt;span class="dt"&gt;Options&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9"&gt;&lt;/a&gt;runCmd opts path &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-10"&gt;&lt;a href="#cb5-10"&gt;&lt;/a&gt;  config &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; readConfig &lt;span class="op"&gt;$&lt;/span&gt; fromMaybe &lt;span class="st"&gt;&amp;quot;./config.yaml&amp;quot;&lt;/span&gt; path   &lt;span class="co"&gt;-- ココと&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-11"&gt;&lt;a href="#cb5-11"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;let&lt;/span&gt; plugin &lt;span class="ot"&gt;=&lt;/span&gt; hsequence&lt;/span&gt;
&lt;span id="cb5-12"&gt;&lt;a href="#cb5-12"&gt;&lt;/a&gt;             &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;logger &lt;span class="op"&gt;&amp;lt;@=&amp;gt;&lt;/span&gt; MixLogger.buildPlugin logOpts&lt;/span&gt;
&lt;span id="cb5-13"&gt;&lt;a href="#cb5-13"&gt;&lt;/a&gt;            &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;config &lt;span class="op"&gt;&amp;lt;@=&amp;gt;&lt;/span&gt; MixConfig.buildPlugin config  &lt;span class="co"&gt;-- ココを追記&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-14"&gt;&lt;a href="#cb5-14"&gt;&lt;/a&gt;            &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; nil&lt;/span&gt;
&lt;span id="cb5-15"&gt;&lt;a href="#cb5-15"&gt;&lt;/a&gt;  Mix.run plugin cmd&lt;/span&gt;
&lt;span id="cb5-16"&gt;&lt;a href="#cb5-16"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-17"&gt;&lt;a href="#cb5-17"&gt;&lt;/a&gt;    logOpts &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;handle &lt;span class="op"&gt;@=&lt;/span&gt; stdout&lt;/span&gt;
&lt;span id="cb5-18"&gt;&lt;a href="#cb5-18"&gt;&lt;/a&gt;           &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;verbose &lt;span class="op"&gt;@=&lt;/span&gt; (opts &lt;span class="op"&gt;^.&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;verbose)&lt;/span&gt;
&lt;span id="cb5-19"&gt;&lt;a href="#cb5-19"&gt;&lt;/a&gt;           &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; nil&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これで次のような YAML 設定ファイルを読み込めるようになった：&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode yaml"&gt;&lt;code class="sourceCode yaml"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;repositories&lt;/span&gt;&lt;span class="kw"&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;-&lt;/span&gt;&lt;span class="at"&gt; matsubara0507/deps-sensor&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;-&lt;/span&gt;&lt;span class="at"&gt; matsubara0507/git-plantation&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;-&lt;/span&gt;&lt;span class="at"&gt; haskell-jp/antenna&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="github-api-で取得"&gt;GitHub API で取得&lt;/h3&gt;
&lt;p&gt;GitHub API も頻繁に使うので&lt;a href="https://github.com/matsubara0507/mix.hs/tree/master/mix-plugin-github"&gt;プラグイン化&lt;/a&gt;してる． 次のように &lt;code&gt;Env&lt;/code&gt; 型を拡張して CLI 経由で渡すことで，&lt;code&gt;RIO Env a&lt;/code&gt; 配下ですっごく簡単に GitHub API を呼び出すことができる：&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- Env の拡張&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Mix.Plugin.GitHub&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;MixGitHub&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Record&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5"&gt;&lt;/a&gt;  &amp;#39;[ &lt;span class="st"&gt;&amp;quot;logger&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;LogFunc&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;github&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;MixGitHub.Token&lt;/span&gt; &lt;span class="co"&gt;-- 追記&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="#cb7-7"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;config&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Config&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-8"&gt;&lt;a href="#cb7-8"&gt;&lt;/a&gt;   ]&lt;/span&gt;
&lt;span id="cb7-9"&gt;&lt;a href="#cb7-9"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-10"&gt;&lt;a href="#cb7-10"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- Main の拡張&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-11"&gt;&lt;a href="#cb7-11"&gt;&lt;/a&gt;&lt;span class="ot"&gt;runCmd ::&lt;/span&gt; &lt;span class="dt"&gt;Options&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb7-12"&gt;&lt;a href="#cb7-12"&gt;&lt;/a&gt;runCmd opts path &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-13"&gt;&lt;a href="#cb7-13"&gt;&lt;/a&gt;  gToken &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; liftIO &lt;span class="op"&gt;$&lt;/span&gt; fromString &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; getEnv &lt;span class="st"&gt;&amp;quot;GH_TOKEN&amp;quot;&lt;/span&gt;     &lt;span class="co"&gt;-- ココと&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-14"&gt;&lt;a href="#cb7-14"&gt;&lt;/a&gt;  config &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; readConfig &lt;span class="op"&gt;$&lt;/span&gt; fromMaybe &lt;span class="st"&gt;&amp;quot;./config.yaml&amp;quot;&lt;/span&gt; path&lt;/span&gt;
&lt;span id="cb7-15"&gt;&lt;a href="#cb7-15"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;let&lt;/span&gt; plugin &lt;span class="ot"&gt;=&lt;/span&gt; hsequence&lt;/span&gt;
&lt;span id="cb7-16"&gt;&lt;a href="#cb7-16"&gt;&lt;/a&gt;             &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;logger &lt;span class="op"&gt;&amp;lt;@=&amp;gt;&lt;/span&gt; MixLogger.buildPlugin logOpts&lt;/span&gt;
&lt;span id="cb7-17"&gt;&lt;a href="#cb7-17"&gt;&lt;/a&gt;            &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;github &lt;span class="op"&gt;&amp;lt;@=&amp;gt;&lt;/span&gt; MixGitHub.buildPlugin gToken  &lt;span class="co"&gt;-- ココを追記&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-18"&gt;&lt;a href="#cb7-18"&gt;&lt;/a&gt;            &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;config &lt;span class="op"&gt;&amp;lt;@=&amp;gt;&lt;/span&gt; MixConfig.buildPlugin config&lt;/span&gt;
&lt;span id="cb7-19"&gt;&lt;a href="#cb7-19"&gt;&lt;/a&gt;            &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; nil&lt;/span&gt;
&lt;span id="cb7-20"&gt;&lt;a href="#cb7-20"&gt;&lt;/a&gt;  Mix.run plugin cmd&lt;/span&gt;
&lt;span id="cb7-21"&gt;&lt;a href="#cb7-21"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-22"&gt;&lt;a href="#cb7-22"&gt;&lt;/a&gt;    &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;呼び出し側はこんな感じ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;DepsSensor.Cmd&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Mix.Plugin.GitHub&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;MixGitHub&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-6"&gt;&lt;a href="#cb8-6"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fetchStackFileContent ::&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;RIO&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; (&lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-7"&gt;&lt;a href="#cb8-7"&gt;&lt;/a&gt;fetchStackFileContent owner name &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-8"&gt;&lt;a href="#cb8-8"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;let&lt;/span&gt; (owner&amp;#39;, name&amp;#39;) &lt;span class="ot"&gt;=&lt;/span&gt; (GitHub.mkName &lt;span class="dt"&gt;Proxy&lt;/span&gt; owner, GitHub.mkName &lt;span class="dt"&gt;Proxy&lt;/span&gt; name)&lt;/span&gt;
&lt;span id="cb8-9"&gt;&lt;a href="#cb8-9"&gt;&lt;/a&gt;  &lt;span class="co"&gt;-- MixGitHub.fetch するだけ，簡単でしょ？&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-10"&gt;&lt;a href="#cb8-10"&gt;&lt;/a&gt;  resp &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; MixGitHub.fetch &lt;span class="op"&gt;$&lt;/span&gt; GitHub.contentsForR owner&amp;#39; name&amp;#39; &lt;span class="st"&gt;&amp;quot;stack.yaml&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-11"&gt;&lt;a href="#cb8-11"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;case&lt;/span&gt; resp &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-12"&gt;&lt;a href="#cb8-12"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Left&lt;/span&gt; _        &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="co"&gt;-- エラー握り潰すのはあれだけど&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-13"&gt;&lt;a href="#cb8-13"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Right&lt;/span&gt; content &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;pure&lt;/span&gt; (toFileContent content)&lt;/span&gt;
&lt;span id="cb8-14"&gt;&lt;a href="#cb8-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-15"&gt;&lt;a href="#cb8-15"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- get-content API の返り値に含まれるファイルの中身だけを取り出す&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-16"&gt;&lt;a href="#cb8-16"&gt;&lt;/a&gt;&lt;span class="ot"&gt;toFileContent ::&lt;/span&gt; &lt;span class="dt"&gt;GitHub.Content&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-17"&gt;&lt;a href="#cb8-17"&gt;&lt;/a&gt;toFileContent &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-18"&gt;&lt;a href="#cb8-18"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;GitHub.ContentFile&lt;/span&gt; c &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; GitHub.contentFileContent c&lt;/span&gt;
&lt;span id="cb8-19"&gt;&lt;a href="#cb8-19"&gt;&lt;/a&gt;  _                    &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="yamlを取り込む"&gt;YAMLを取り込む&lt;/h3&gt;
&lt;p&gt;yaml パッケージを使ってサクッと YAML のデコードをするために，必要な情報だけの簡単なデータ型を作っておく：&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;DepsSensor.Cmd&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-2"&gt;&lt;a href="#cb9-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-3"&gt;&lt;a href="#cb9-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;StackFile&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Record&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-4"&gt;&lt;a href="#cb9-4"&gt;&lt;/a&gt;  &amp;#39;[ &lt;span class="st"&gt;&amp;quot;resolver&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-5"&gt;&lt;a href="#cb9-5"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;snapshot&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-6"&gt;&lt;a href="#cb9-6"&gt;&lt;/a&gt;   ]&lt;/span&gt;
&lt;span id="cb9-7"&gt;&lt;a href="#cb9-7"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-8"&gt;&lt;a href="#cb9-8"&gt;&lt;/a&gt;&lt;span class="ot"&gt;toResolver ::&lt;/span&gt; &lt;span class="dt"&gt;StackFile&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-9"&gt;&lt;a href="#cb9-9"&gt;&lt;/a&gt;toResolver stackFile &lt;span class="ot"&gt;=&lt;/span&gt; stackFile &lt;span class="op"&gt;^.&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;resolver &lt;span class="op"&gt;&amp;lt;|&amp;gt;&lt;/span&gt; stackFile &lt;span class="op"&gt;^.&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;snapshot&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;実は1つ問題があって，get-content API で取得した中身は Base64 エンコードされているのだ． なので &lt;code&gt;fetchStackFileContent&lt;/code&gt; 関数で取得した &lt;code&gt;Text&lt;/code&gt; 型の値を Base64 デコードする関数を用意しておこう：&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;RIO.Text&lt;/span&gt;                &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;T&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.ByteArray.Encoding&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;BA&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="#cb10-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.Yaml&lt;/span&gt;               &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;Y&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="#cb10-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="#cb10-5"&gt;&lt;/a&gt;&lt;span class="ot"&gt;decodeStackFile ::&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Either&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="dt"&gt;StackFile&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="#cb10-6"&gt;&lt;/a&gt;decodeStackFile dat &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="#cb10-7"&gt;&lt;/a&gt;  &lt;span class="co"&gt;-- 改行コードを含むので抜いて連結してから memory パッケージを使ってデコードしている&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-8"&gt;&lt;a href="#cb10-8"&gt;&lt;/a&gt;  dat&amp;#39; &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; BA.convertFromBase &lt;span class="dt"&gt;BA.Base64&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; T.encodeUtf8 (&lt;span class="fu"&gt;mconcat&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; T.lines dat)&lt;/span&gt;
&lt;span id="cb10-9"&gt;&lt;a href="#cb10-9"&gt;&lt;/a&gt;  mapLeft &lt;span class="fu"&gt;show&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; Y.decodeEither&amp;#39; dat&amp;#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ちなみに，&lt;a href="https://hackage.haskell.org/package/memory"&gt;memory パッケージ&lt;/a&gt;を使っているのは &lt;a href="https://hackage.haskell.org/package/cryptonite"&gt;cryptonite パッケージ&lt;/a&gt;でも利用されているから．&lt;/p&gt;
&lt;h3 id="組み合わせる"&gt;組み合わせる&lt;/h3&gt;
&lt;p&gt;準備は整ったのでこれを連結した処理をループで回すだけだ． ただ，用意したほとんどの関数が &lt;code&gt;Maybe a&lt;/code&gt; 型か &lt;code&gt;Either e a&lt;/code&gt; 型を返すので，このままエラーハンドリングすると段々畑になってしまう． そこで重宝するのが &lt;a href="https://github.com/matsubara0507/fallible"&gt;fallible パッケージ&lt;/a&gt;だ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;RIO.Text&lt;/span&gt;          &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;T&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt;           &lt;span class="dt"&gt;Data.Fallible&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-3"&gt;&lt;a href="#cb11-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Mix.Plugin.Logger&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;MixLogger&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-4"&gt;&lt;a href="#cb11-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-5"&gt;&lt;a href="#cb11-5"&gt;&lt;/a&gt;&lt;span class="ot"&gt;cmd ::&lt;/span&gt; &lt;span class="dt"&gt;RIO&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb11-6"&gt;&lt;a href="#cb11-6"&gt;&lt;/a&gt;cmd &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-7"&gt;&lt;a href="#cb11-7"&gt;&lt;/a&gt;  repositories &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; asks (view &lt;span class="op"&gt;#&lt;/span&gt;repositories &lt;span class="op"&gt;.&lt;/span&gt; view &lt;span class="op"&gt;#&lt;/span&gt;config)&lt;/span&gt;
&lt;span id="cb11-8"&gt;&lt;a href="#cb11-8"&gt;&lt;/a&gt;  for_ repositories &lt;span class="op"&gt;$&lt;/span&gt; \repo &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; evalContT &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-9"&gt;&lt;a href="#cb11-9"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; (owner, name) &lt;span class="ot"&gt;=&lt;/span&gt; T.drop &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; T.break (&lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="ch"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;) repo&lt;/span&gt;
&lt;span id="cb11-10"&gt;&lt;a href="#cb11-10"&gt;&lt;/a&gt;    content   &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; lift (fetchStackFileContent owner name) &lt;span class="op"&gt;!??&lt;/span&gt; warn repo &lt;span class="st"&gt;&amp;quot;stack.yaml is not found&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-11"&gt;&lt;a href="#cb11-11"&gt;&lt;/a&gt;    stackFile &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; decodeStackFile content &lt;span class="op"&gt;??=&lt;/span&gt; warn repo&lt;/span&gt;
&lt;span id="cb11-12"&gt;&lt;a href="#cb11-12"&gt;&lt;/a&gt;    resolver  &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; toResolver stackFile &lt;span class="op"&gt;???&lt;/span&gt; warn repo &lt;span class="st"&gt;&amp;quot;undefined resolver&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-13"&gt;&lt;a href="#cb11-13"&gt;&lt;/a&gt;    MixLogger.logInfo (display &lt;span class="op"&gt;$&lt;/span&gt; repo &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;: &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; resolver)&lt;/span&gt;
&lt;span id="cb11-14"&gt;&lt;a href="#cb11-14"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-15"&gt;&lt;a href="#cb11-15"&gt;&lt;/a&gt;    &lt;span class="co"&gt;-- とりあえず警告するだけ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-16"&gt;&lt;a href="#cb11-16"&gt;&lt;/a&gt;    warn r msg &lt;span class="ot"&gt;=&lt;/span&gt; exit &lt;span class="op"&gt;$&lt;/span&gt; MixLogger.logWarn (display &lt;span class="op"&gt;$&lt;/span&gt; T.pack msg &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;: &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; r)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;演算子が3種類も出てきてわかりにくいが - 左が &lt;code&gt;!&lt;/code&gt; の場合は左辺が &lt;code&gt;RIO Env (f a)&lt;/code&gt; になっていて， &lt;code&gt;?&lt;/code&gt; の場合は &lt;code&gt;f a&lt;/code&gt; になっている（&lt;code&gt;f&lt;/code&gt; は &lt;code&gt;Maybe&lt;/code&gt; や &lt;code&gt;Either e&lt;/code&gt;） - 右が &lt;code&gt;=&lt;/code&gt; の場合は右辺で &lt;code&gt;Either e a&lt;/code&gt; の &lt;code&gt;e&lt;/code&gt; を受け取るハンドリングをし，&lt;code&gt;?&lt;/code&gt; の場合は無視する（&lt;code&gt;Maybe&lt;/code&gt; の場合は後者一択）&lt;/p&gt;
&lt;p&gt;で，これを実行するとこんな感じになった：&lt;/p&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb12-1"&gt;&lt;a href="#cb12-1"&gt;&lt;/a&gt;$ &lt;span class="ex"&gt;stack&lt;/span&gt; exec -- deps-sensor&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="#cb12-2"&gt;&lt;/a&gt;&lt;span class="ex"&gt;matsubara0507&lt;/span&gt;/deps-sensor: &lt;span class="ex"&gt;lts-15.13&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="#cb12-3"&gt;&lt;/a&gt;&lt;span class="ex"&gt;matsubara0507&lt;/span&gt;/git-plantation: &lt;span class="ex"&gt;lts-15.5&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-4"&gt;&lt;a href="#cb12-4"&gt;&lt;/a&gt;&lt;span class="ex"&gt;haskell-jp&lt;/span&gt;/antenna: &lt;span class="ex"&gt;lts-14.20&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id="おしまい"&gt;おしまい&lt;/h1&gt;
&lt;p&gt;追々，Webページの生成と http://packdeps.haskellers.com っぽい機能を足したりするつもりです。&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/05/16/165316</id><title type="text">FutureとUnpin</title><updated>2020-05-29T09:52:26+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/05/16/165316"/><summary type="html">Future で Unpin が必要なときは pin してねって書いてある。 Pinning - Asynchronous Programming in Rust To use a Future or Stream that isn't Unpin with a function that requires Unpin types, you'll first have to pin the value Box も Unpin なので、 Pin する必要ないのではと一瞬考える。 boxed.rs.html -- source impl&lt;T: ?Sized&gt; Unpin for Box {} しか…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/03/10/081837</id><title type="text">doesn't have a size known at compile-time</title><updated>2020-05-23T14:49:09+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/03/10/081837"/><summary type="html">まだ時間がなくて詳しくは調べてないけど、こういう書き方はできない。まあそうかなと思う。 use std::fmt::Display; struct S&lt;T&gt; (T); fn main() { let s: Box&lt;S&lt;dyn Display&gt;&gt; = Box::new(S("")); } Compiling playground v0.0.1 (/playground) error[E0277]: the size for values of type `dyn std::fmt::Display` cannot be known at compilation time --&gt; src/lib.…</summary></entry><entry><id>https://kurokawh.blogspot.com/2019/11/mac-mojava.html</id><title type="text">[mac] Mojavaクリーンインストール</title><updated>2020-05-06T17:02:25.994+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2019/11/mac-mojava.html"/><summary type="text">Mojavaへのアップデートを契機にmac book airを初期化して環境をクリーンセットアップしました。
自分にとって使いやすい環境の設定手順および、インストールしたアプリ群の情報をメモがわりに残しておきます。



システム環境設定

トラックパッド

軌跡の速さを速くする 
「スクロールとズーム」内の「スクロールの方向」を「ナチュラル」にする
「その他のジェスチャー」内の全てのチェックを外す

アクセシビリティ

マウスとトラックパッド

トラックパッドオプション

「ドラッグを有効にする」にチェック

→ダブルタップでドラッグできるようになる

「ドラッグロックなし」を選択

→トラックパッドから手を離すとドラッグ解除





キーボード

キーボード

F1, F2などのキーを標準のファンクションキーとして利用する：チェック
修飾キー：ControlとOptionを</summary></entry><entry><id>https://kurokawh.blogspot.com/2020/05/linux-gnupg.html</id><title type="text">[linux] gnupgによる暗号化処理時の確認プロンプトを抑制する方法</title><updated>2020-05-06T16:37:57.790+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2020/05/linux-gnupg.html"/><summary type="text">gnupgを用いてファイルを暗号化する際、予めインポートした公開鍵に対してtrust設定をしておかないと、指定した公開鍵毎に以下のような警告が発せられます。


% gpg -e -r abc@test.org a.txt 
gpg: AAAA4C0DD6F2ZZZZ: この鍵が本当に本人のものである、という兆候が、ありません

sub  elg2048/AAAA4C0DD6F2ZZZZ 2020-05-06 Hiroyuki Kurokawa &lt;abc@test.org&gt;
  主鍵フィンガープリント: &lt;snip&gt;
  副鍵フィンガープリント: &lt;snip&gt;

この鍵は、このユーザIDをなのる本人のものかどうか確信でき
ません。今から行うことを＊本当に＊理解していない場合には、
次の質問にはnoと答えてください。

それでもこの鍵を使いますか? (y/N)

以下のオプションを指定する</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/05/04/215714</id><title type="text">AVL木</title><updated>2020-05-04T21:58:51+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/05/04/215714"/><summary type="html">確か、いい感じに深くなりすぎない木だよね。回転？なにそれ？みたいな状態から実装し始めたら、面倒で死ぬかと思った。 AVL Tree by Java -- これで分かったAVL木 とか AVL木の回転(要素の挿入や削除のしかた) - Qiita とかを参考に実装した。２週間くらい前から２回ほどチャレンジしてギブアップしていて、本日、腰を据えて三度目の正直。コードを整形する気力が残ってないので、そのまま貼り付け。 type 'a btree = | Node of int * 'a * 'a btree * 'a btree | Leaf ;; let rotate_right t = match…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2020/04/29/170208</id><title type="text">家から出ない生活４週間</title><updated>2020-04-29T17:10:29+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2020/04/29/170208"/><summary type="html">出社非推奨になったのを機に家から出ない生活を始めて４週間が経った。今までやったことをまとめていく。 食料品 せっかくだから生活で縛りプレイをしてみようと思って Amazon と Yodobashi を禁止にしている。この２社は最近評判が良くないこともあるし。 業務スーパーの通販 いわゆるネットスーパーはサイトが激重になっていたり配達可能日がすべて☓になっていたりで機能不全を起こしているようだった。そこで飲食店がメインターゲットであろう業務スーパーなら今空いているだろうという読み。ここではピザ材料、冷凍野菜、割り箸などを入手している。 とにかく業務スーパーの通販を最大限利用するには冷凍室の容積が…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2020-04-20-servant-with-slack-verifying-requests.html</id><title type="text">Haskell Servant で Slack からの署名付きリクエストを受ける</title><updated>2020-04-20T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2020-04-20-servant-with-slack-verifying-requests.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;Slack のスラッシュコマンドなどで利用される署名付きリクエストを Haskell Servant で受ける方法を考えて実装しました． 実装は slackell という Haskell の Slack API パッケージにしてあります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/matsubara0507/slackell"&gt;matsubara0507/slackell - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://github.com/matsubara0507/slackell/pull/1"&gt;該当 PR はこれです&lt;/a&gt;．&lt;/p&gt;
&lt;h2 id="署名付きリクエスト"&gt;署名付きリクエスト&lt;/h2&gt;
&lt;p&gt;スラッシュコマンドなどで Slack からのリクエストを受け取るときに，そのリクエストが本当に該当のスラッシュコマンドから送られてきた正しいリクエストかを検証するには，リクエストパラメーターとして送られてきた検証トークンを確認していた． しかし，この方法は現在では非推奨になっており，代わりにリクエストヘッダーに付いている署名を確認する． 公式ドキュメントは以下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://api.slack.com/authentication/verifying-requests-from-slack"&gt;Verifying requests from Slack | Slack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;署名は &lt;code&gt;X-Slack-Signature&lt;/code&gt; というヘッダーに &lt;code&gt;v0=&lt;/code&gt; というプレフィックス付きで含まれている． このリクエストを受け取ったアプリケーション側は以下の方法で署名をエンコードして比較することで，そのリクエストの正当性を保証する：&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;&lt;code&gt;X-Slack-Request-Timestamp&lt;/code&gt; リクエストヘッダーに含まれているタイムスタンプを読む&lt;/li&gt;
&lt;li&gt;バージョン番号・1のタイムスタンプ・リクエストボディの3つを &lt;code&gt;:&lt;/code&gt; 区切りで連結する
&lt;ul&gt;
&lt;li&gt;e.g. &lt;code&gt;v0:123456789:command=/weather&amp;amp;text=94070&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;バージョン番号は今のところ全て &lt;code&gt;v0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;2の文字列を Slack Apps で取得できる &lt;code&gt;Signing Secret&lt;/code&gt; を使って HMAC SHA256 でエンコード&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="haskellでエンコードする"&gt;Haskellでエンコードする&lt;/h3&gt;
&lt;p&gt;このアルゴリズムを Haskell プログラムで実装する． HMAC SHA256 エンコードには &lt;a href="https://hackage.haskell.org/package/cryptonite"&gt;cryptonite&lt;/a&gt; パッケージを使った． 2と3の部分を行って署名をエンコードする関数は以下：&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Web.Slack.Verify&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Crypto.Hash&lt;/span&gt; (&lt;span class="dt"&gt;Digest&lt;/span&gt;, &lt;span class="dt"&gt;SHA256&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Crypto.MAC.HMAC&lt;/span&gt; (&lt;span class="dt"&gt;HMAC&lt;/span&gt; (..), hmac)&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;SigningSecret&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;SigningSecret&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt; &lt;span class="kw"&gt;deriving&lt;/span&gt; (&lt;span class="dt"&gt;IsString&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;RequestTimestamp&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-9"&gt;&lt;a href="#cb1-9"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | シークレット・タイムスタンプ・リクエストボディは引数でもらう&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-10"&gt;&lt;a href="#cb1-10"&gt;&lt;/a&gt;&lt;span class="ot"&gt;encodeSignature ::&lt;/span&gt; &lt;span class="dt"&gt;SigningSecret&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;RequestTimestamp&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;ByteString&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Digest&lt;/span&gt; &lt;span class="dt"&gt;SHA256&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-11"&gt;&lt;a href="#cb1-11"&gt;&lt;/a&gt;encodeSignature (&lt;span class="dt"&gt;SigningSecret&lt;/span&gt; secret) ts body &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-12"&gt;&lt;a href="#cb1-12"&gt;&lt;/a&gt;  hmacGetDigest &lt;span class="op"&gt;$&lt;/span&gt; hmac (Text.encodeUtf8 secret) basestr&lt;/span&gt;
&lt;span id="cb1-13"&gt;&lt;a href="#cb1-13"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-14"&gt;&lt;a href="#cb1-14"&gt;&lt;/a&gt;    basestr &lt;span class="ot"&gt;=&lt;/span&gt; BS.intercalate &lt;span class="st"&gt;&amp;quot;:&amp;quot;&lt;/span&gt; [Text.encodeUtf8 version, Text.encodeUtf8 ts, body]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最終的な型が &lt;code&gt;Digest SHA256&lt;/code&gt; なので，ヘッダーの方の署名と比較しやすいように文字列からの変換関数も用意しておく：&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Crypto.Hash&lt;/span&gt; (&lt;span class="dt"&gt;Digest&lt;/span&gt;, &lt;span class="dt"&gt;SHA256&lt;/span&gt;, digestFromByteString)&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.ByteArray.Encoding&lt;/span&gt; (&lt;span class="dt"&gt;Base&lt;/span&gt; (..), convertFromBase)&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;SignatureHeader&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6"&gt;&lt;/a&gt;&lt;span class="ot"&gt;convertSignatureHeader ::&lt;/span&gt; &lt;span class="dt"&gt;SignatureHeader&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; (&lt;span class="dt"&gt;Digest&lt;/span&gt; &lt;span class="dt"&gt;SHA256&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7"&gt;&lt;/a&gt;convertSignatureHeader sign &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;either&lt;/span&gt; (&lt;span class="fu"&gt;const&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;) digestFromByteString bs&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9"&gt;&lt;/a&gt;    (_, sign&amp;#39;) &lt;span class="ot"&gt;=&lt;/span&gt; Text.breakOnEnd (version &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;=&amp;quot;&lt;/span&gt;) sign&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="#cb2-10"&gt;&lt;/a&gt;    bs &lt;span class="ot"&gt;=&lt;/span&gt; convertFromBase &lt;span class="dt"&gt;Base16&lt;/span&gt; (Text.encodeUtf8 sign&amp;#39;)&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Either&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="dt"&gt;ByteString&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="#cb2-11"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-12"&gt;&lt;a href="#cb2-12"&gt;&lt;/a&gt;&lt;span class="ot"&gt;version ::&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-13"&gt;&lt;a href="#cb2-13"&gt;&lt;/a&gt;version &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;v0&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ここで注意しなければいけないのが &lt;code&gt;digestFromByteString&lt;/code&gt; 関数に食わせる &lt;code&gt;ByteString&lt;/code&gt; 型の値は， &lt;code&gt;memory&lt;/code&gt; パッケージの関数を利用して16進数表現から直す必要がある．&lt;/p&gt;
&lt;h2 id="slash-command-を受け取る"&gt;Slash Command を受け取る&lt;/h2&gt;
&lt;p&gt;署名をエンコードする関数はできたので，あとは Servant でスラッシュコマンドを受け取る方法を考える． まずはスラッシュコマンドから送られてくるリクエストボディの型を宣言しておこう：&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Web.Slack.SlashCommand&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Extensible&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;RequestData&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Record&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6"&gt;&lt;/a&gt;  &amp;#39;[ &lt;span class="st"&gt;&amp;quot;token&amp;quot;&lt;/span&gt;           &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;command&amp;quot;&lt;/span&gt;         &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;            &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;response_url&amp;quot;&lt;/span&gt;    &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;trigger_id&amp;quot;&lt;/span&gt;      &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;user_id&amp;quot;&lt;/span&gt;         &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;user_name&amp;quot;&lt;/span&gt;       &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-13"&gt;&lt;a href="#cb3-13"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;team_id&amp;quot;&lt;/span&gt;         &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-14"&gt;&lt;a href="#cb3-14"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;team_domain&amp;quot;&lt;/span&gt;     &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-15"&gt;&lt;a href="#cb3-15"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;channel_id&amp;quot;&lt;/span&gt;      &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-16"&gt;&lt;a href="#cb3-16"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;channel_name&amp;quot;&lt;/span&gt;    &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-17"&gt;&lt;a href="#cb3-17"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;enterprise_id&amp;quot;&lt;/span&gt;   &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-18"&gt;&lt;a href="#cb3-18"&gt;&lt;/a&gt;   , &lt;span class="st"&gt;&amp;quot;enterprise_name&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-19"&gt;&lt;a href="#cb3-19"&gt;&lt;/a&gt;   ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;正直，これを調べるのも大変だった． 公式ドキュメントにはどんなパラメータがあるか割愛されてる部分があるからだ．&lt;/p&gt;
&lt;p&gt;で，API の型は雰囲気としてはこんな感じ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- Web.Slack は slackell&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Web.Slack.Verify&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;Slack&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Web.Slack.SlashCommand&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;SlashCmd&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-5"&gt;&lt;a href="#cb4-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;API&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-6"&gt;&lt;a href="#cb4-6"&gt;&lt;/a&gt;    &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;slash&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-7"&gt;&lt;a href="#cb4-7"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;ReqBody&lt;/span&gt; &amp;#39;[&lt;span class="dt"&gt;FormUrlEncoded&lt;/span&gt;] &lt;span class="dt"&gt;RequestData&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-8"&gt;&lt;a href="#cb4-8"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Header&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;X-Slack-Request-Timestamp&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;Slack.RequestTimestamp&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-9"&gt;&lt;a href="#cb4-9"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Header&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;X-Slack-Signature&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;Slack.SignatureHeader&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-10"&gt;&lt;a href="#cb4-10"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Post&lt;/span&gt; &amp;#39;[&lt;span class="dt"&gt;JSON&lt;/span&gt;] &lt;span class="dt"&gt;NoContent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ここで問題が1つ． 署名をエンコードするのに必要なのはデータ型 &lt;code&gt;SlachCmd.RequestData&lt;/code&gt; に変換される前の文字列だ． &lt;code&gt;ToForm&lt;/code&gt; 型クラスを使って元の形（&lt;code&gt;=&lt;/code&gt; と &lt;code&gt;&amp;amp;&lt;/code&gt; で連結するやつ）に戻せば良いと思うかも知れないが，これだと key の順番が変わってしまう可能性があり，順番が変わると別のエンコード結果になってしまう． 逆に文字列のまんま受け取れば良いかと思うかも知れないが，Servant は正しい ContentType な型を指定しないと 400 を返してしまう（スラッシュコマンドは &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt; でリクエストしてくる）． 困った． 色々調べたが，後から素のリクエストボディを取得する方法がわからなかった…&lt;/p&gt;
&lt;h3 id="contenttypeを自作する"&gt;ContentTypeを自作する&lt;/h3&gt;
&lt;p&gt;まぁ無いなら自作するしかない． 素の文字列を返してくれて &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt; メディアタイプを表している ContentType な型を作る． どのメディアタイプかは &lt;code&gt;Accept&lt;/code&gt; 型クラスで定義し，どの型で返してくれるかは &lt;code&gt;MimeUnrender&lt;/code&gt; 型クラスで定義する：&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Web.Slack.SlashCommand&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;RequestData&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;SlashCommand&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;Accept&lt;/span&gt; &lt;span class="dt"&gt;SlashCommand&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8"&gt;&lt;/a&gt;&lt;span class="ot"&gt;  contentType ::&lt;/span&gt; &lt;span class="dt"&gt;Proxy&lt;/span&gt; &lt;span class="dt"&gt;SlashCommand&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;MediaType&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9"&gt;&lt;/a&gt;  contentType _ &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;application&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;M.//&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x-www-form-urlencoded&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-10"&gt;&lt;a href="#cb5-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-11"&gt;&lt;a href="#cb5-11"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;MimeUnrender&lt;/span&gt; &lt;span class="dt"&gt;SlashCommand&lt;/span&gt; (&lt;span class="dt"&gt;ByteString&lt;/span&gt;, &lt;span class="dt"&gt;RequestData&lt;/span&gt;) &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-12"&gt;&lt;a href="#cb5-12"&gt;&lt;/a&gt;&lt;span class="ot"&gt;  mimeUnrender ::&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-13"&gt;&lt;a href="#cb5-13"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Proxy&lt;/span&gt; &lt;span class="dt"&gt;SlashCommand&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Lazy.ByteString&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Either&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; (&lt;span class="dt"&gt;ByteString&lt;/span&gt;, &lt;span class="dt"&gt;RequestData&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb5-14"&gt;&lt;a href="#cb5-14"&gt;&lt;/a&gt;  mimeUnrender _ bs &lt;span class="ot"&gt;=&lt;/span&gt; Text.unpack &lt;span class="op"&gt;+++&lt;/span&gt; (bs,) &lt;span class="op"&gt;$&lt;/span&gt; urlDecodeAsForm bs&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;どーせ後から &lt;code&gt;RequestData&lt;/code&gt; 型に変換するので両方を返すことにした． あとはこれを使うだけ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- Web.Slack は slackell&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Web.Slack.Verify&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;Slack&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Web.Slack.SlashCommand&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;SlashCmd&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt;           &lt;span class="dt"&gt;Web.Slack.SlashCommand&lt;/span&gt; (&lt;span class="dt"&gt;SlashCommand&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-6"&gt;&lt;a href="#cb6-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;API&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-7"&gt;&lt;a href="#cb6-7"&gt;&lt;/a&gt;    &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;slash&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-8"&gt;&lt;a href="#cb6-8"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;ReqBody&lt;/span&gt; &amp;#39;[&lt;span class="dt"&gt;SlashCommand&lt;/span&gt;] &lt;span class="dt"&gt;RequestData&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-9"&gt;&lt;a href="#cb6-9"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Header&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;X-Slack-Request-Timestamp&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;Slack.RequestTimestamp&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-10"&gt;&lt;a href="#cb6-10"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Header&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;X-Slack-Signature&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;Slack.SignatureHeader&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-11"&gt;&lt;a href="#cb6-11"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Post&lt;/span&gt; &amp;#39;[&lt;span class="dt"&gt;JSON&lt;/span&gt;] &lt;span class="dt"&gt;NoContent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="apiの実装"&gt;APIの実装&lt;/h3&gt;
&lt;p&gt;残りは今までのを使うだけなので簡単：&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;server ::&lt;/span&gt; &lt;span class="dt"&gt;Slack.SigningSecret&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Server&lt;/span&gt; &lt;span class="dt"&gt;API&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2"&gt;&lt;/a&gt;server secret &lt;span class="ot"&gt;=&lt;/span&gt; slashCommand&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4"&gt;&lt;/a&gt;    slashCommand (lbs, body) (&lt;span class="dt"&gt;Just&lt;/span&gt; ts) (&lt;span class="dt"&gt;Just&lt;/span&gt; sign) &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;let&lt;/span&gt; digest &lt;span class="ot"&gt;=&lt;/span&gt; Slack.encodeSignature secret ts (LBS.toStrict lbs) &lt;span class="kw"&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;if&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; digest &lt;span class="op"&gt;==&lt;/span&gt; Slack.convertSignatureHeader sign &lt;span class="kw"&gt;then&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="#cb7-7"&gt;&lt;/a&gt;        liftIO &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-8"&gt;&lt;a href="#cb7-8"&gt;&lt;/a&gt;          _ &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; forkIO &lt;span class="op"&gt;$&lt;/span&gt; action body &lt;span class="co"&gt;-- タイムアウトがあるので処理自体は fork する&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-9"&gt;&lt;a href="#cb7-9"&gt;&lt;/a&gt;          &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="dt"&gt;NoContent&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-10"&gt;&lt;a href="#cb7-10"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-11"&gt;&lt;a href="#cb7-11"&gt;&lt;/a&gt;        throwError err401&lt;/span&gt;
&lt;span id="cb7-12"&gt;&lt;a href="#cb7-12"&gt;&lt;/a&gt;    slashCommand _ _ _ &lt;span class="ot"&gt;=&lt;/span&gt; throwError err401&lt;/span&gt;
&lt;span id="cb7-13"&gt;&lt;a href="#cb7-13"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-14"&gt;&lt;a href="#cb7-14"&gt;&lt;/a&gt;&lt;span class="ot"&gt;    action ::&lt;/span&gt; &lt;span class="dt"&gt;SlashCmd.RequestData&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb7-15"&gt;&lt;a href="#cb7-15"&gt;&lt;/a&gt;    action body &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="おまけfromformインスタンス"&gt;おまけ：FromFormインスタンス&lt;/h2&gt;
&lt;p&gt;実はこれだkではビルドが通らない． というのも，拡張可能データ型の &lt;code&gt;FromForm&lt;/code&gt; 型クラスインスタンスが無いからだ． しょうがないので自作した：&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Web.FormUrlEncoded&lt;/span&gt; (&lt;span class="dt"&gt;FromForm&lt;/span&gt; (..))&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Web.HttpApiData&lt;/span&gt; (&lt;span class="dt"&gt;FromHttpApiData&lt;/span&gt; (..), parseUnique)&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;Forall&lt;/span&gt; (&lt;span class="dt"&gt;KeyTargetAre&lt;/span&gt; &lt;span class="dt"&gt;KnownSymbol&lt;/span&gt; &lt;span class="dt"&gt;FromFormData&lt;/span&gt;) xs &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;FromForm&lt;/span&gt; (&lt;span class="dt"&gt;Record&lt;/span&gt; xs) &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5"&gt;&lt;/a&gt;  fromForm form &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-6"&gt;&lt;a href="#cb8-6"&gt;&lt;/a&gt;    hgenerateFor (&lt;span class="dt"&gt;Proxy&lt;/span&gt; &lt;span class="op"&gt;@&lt;/span&gt; (&lt;span class="dt"&gt;KeyTargetAre&lt;/span&gt; &lt;span class="dt"&gt;KnownSymbol&lt;/span&gt; &lt;span class="dt"&gt;FromFormData&lt;/span&gt;)) &lt;span class="op"&gt;$&lt;/span&gt; \m &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-7"&gt;&lt;a href="#cb8-7"&gt;&lt;/a&gt;      &lt;span class="dt"&gt;Field&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; parseUnique (stringKeyOf m) form&lt;/span&gt;
&lt;span id="cb8-8"&gt;&lt;a href="#cb8-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-9"&gt;&lt;a href="#cb8-9"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- Identity のインスタンスぐらい宣言しておいてよ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-10"&gt;&lt;a href="#cb8-10"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromHttpApiData&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;FromHttpApiData&lt;/span&gt; (&lt;span class="dt"&gt;Identity&lt;/span&gt; a) &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-11"&gt;&lt;a href="#cb8-11"&gt;&lt;/a&gt;  parseUrlPiece &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;fmap&lt;/span&gt; &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;.&lt;/span&gt; parseUrlPiece&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これの欠点が1つ． &lt;code&gt;parseUnique&lt;/code&gt; 関数の &lt;code&gt;Maybe a&lt;/code&gt; 型に関する振る舞いだ． &lt;code&gt;Maybe a&lt;/code&gt; 型なら該当の key が含まれなければ &lt;code&gt;Nothing&lt;/code&gt; で key があれば &lt;code&gt;Just v&lt;/code&gt; になって欲しい． しかし実際はこうだ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; parseUnique &lt;span class="st"&gt;&amp;quot;age&amp;quot;&lt;/span&gt; [(&lt;span class="st"&gt;&amp;quot;age&amp;quot;&lt;/span&gt;, &lt;span class="st"&gt;&amp;quot;Just 25&amp;quot;&lt;/span&gt;)]&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Either&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt; (&lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb9-2"&gt;&lt;a href="#cb9-2"&gt;&lt;/a&gt;&lt;span class="dt"&gt;Right&lt;/span&gt; (&lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="dv"&gt;25&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;現実のリクエストが &lt;code&gt;&amp;quot;Just hoge&amp;quot;&lt;/code&gt; なんて送ってくるわけが無い！ しょうがないので自作した：&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; &lt;span class="dt"&gt;FromFormData&lt;/span&gt; a &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2"&gt;&lt;/a&gt;&lt;span class="ot"&gt;  parseUnique&amp;#39; ::&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Form&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Either&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="#cb10-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="#cb10-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromFormData&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;   &lt;span class="kw"&gt;where&lt;/span&gt; parseUnique&amp;#39; &lt;span class="ot"&gt;=&lt;/span&gt; parseUnique&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="#cb10-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromFormData&lt;/span&gt; &lt;span class="dt"&gt;Float&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt; parseUnique&amp;#39; &lt;span class="ot"&gt;=&lt;/span&gt; parseUnique&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="#cb10-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromFormData&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;  &lt;span class="kw"&gt;where&lt;/span&gt; parseUnique&amp;#39; &lt;span class="ot"&gt;=&lt;/span&gt; parseUnique&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="#cb10-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromFormData&lt;/span&gt; &lt;span class="dt"&gt;Char&lt;/span&gt;  &lt;span class="kw"&gt;where&lt;/span&gt; parseUnique&amp;#39; &lt;span class="ot"&gt;=&lt;/span&gt; parseUnique&lt;/span&gt;
&lt;span id="cb10-8"&gt;&lt;a href="#cb10-8"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromFormData&lt;/span&gt; &lt;span class="dt"&gt;Text&lt;/span&gt;  &lt;span class="kw"&gt;where&lt;/span&gt; parseUnique&amp;#39; &lt;span class="ot"&gt;=&lt;/span&gt; parseUnique&lt;/span&gt;
&lt;span id="cb10-9"&gt;&lt;a href="#cb10-9"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-10"&gt;&lt;a href="#cb10-10"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromHttpApiData&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;FromFormData&lt;/span&gt; (&lt;span class="dt"&gt;Maybe&lt;/span&gt; a) &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-11"&gt;&lt;a href="#cb10-11"&gt;&lt;/a&gt;  parseUnique&amp;#39; key form &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-12"&gt;&lt;a href="#cb10-12"&gt;&lt;/a&gt;    mv &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; lookupMaybe key form&lt;/span&gt;
&lt;span id="cb10-13"&gt;&lt;a href="#cb10-13"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;case&lt;/span&gt; mv &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-14"&gt;&lt;a href="#cb10-14"&gt;&lt;/a&gt;      &lt;span class="dt"&gt;Just&lt;/span&gt; v  &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; parseQueryParam v&lt;/span&gt;
&lt;span id="cb10-15"&gt;&lt;a href="#cb10-15"&gt;&lt;/a&gt;      &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;で，&lt;code&gt;parseUnique&lt;/code&gt; の代わりに &lt;code&gt;parseUnique&amp;#39;&lt;/code&gt; を使うように &lt;code&gt;FromForm&lt;/code&gt; 型クラスのインスタンスを書き換えるだけだ． これは汎用的なので&lt;a href="https://github.com/matsubara0507/extensible-ext/tree/master/extensible-http-api-data"&gt;別のリポジトリに切り分けた&lt;/a&gt;．&lt;/p&gt;
&lt;h2 id="おしまい"&gt;おしまい&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/matsubara0507/slackell/tree/master/example"&gt;サンプルコード&lt;/a&gt;を作ってスラッシュコマンドのデバッグをしたが，間にちゃんとリクエスト・レスポンスをロギングする仕組みを省いたせいで超大変だった笑．&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2019/12/25/224329</id><title type="text">barbies-thで気軽にHKDを堪能しよう [Haskell AdC 14]</title><updated>2020-04-19T22:45:05+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2019/12/25/224329"/><summary type="html">ミーハーな読者なら、barbiesというライブラリをご存知の方も多いと思う。そう、HKDを扱う定番ライブラリだ。HKDは、同アドベントカレンダーにも寄稿されている他、Haskell Dayでも紹介された(https://assets.adobe.com/public/b93f214d-58c2-482f-5528-a939d3e83660)注目の技法だ。Higher-Kinded Data (HKD) について - Qiita HKDは、一番簡単な場合であるはずのIdentityを使うと着脱が面倒になるという問題がよく知られている。Data.Barbie.BareモジュールのWearという型族…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2020-04-06-servant-auth-with-github-apps.html</id><title type="text">Haskell Servant に GitHub Apps による認証を追加する</title><updated>2020-04-06T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2020-04-06-servant-auth-with-github-apps.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;時々みる「GitHubでログイン」っぽいのを Servant 製サンプルアプリケーションに実装します．&lt;/p&gt;
&lt;p&gt;サンプルアプリケーションは2年前に書いた「&lt;a href="/posts/2017-09-17-create-haskell-and-elm.html"&gt;Haskell × Elm のサンプルアプリケーションを書いてみた&lt;/a&gt;」という記事のものを，最近の GHC や Elm でリファクタリングして使います． これは簡単な ToDo アプリケーションです：&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/create-haskell-and-elm/sample.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;最終的な実装 PR は&lt;a href="https://github.com/matsubara0507/haskell-and-elm/pull/2"&gt;これ&lt;/a&gt;．&lt;/p&gt;
&lt;h2 id="github-apps-による認証"&gt;GitHub Apps による認証&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps"&gt;公式ドキュメント&lt;/a&gt;より&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;GitHub で Apps を登録する
&lt;ul&gt;
&lt;li&gt;Client ID・Client Secret を取得&lt;/li&gt;
&lt;li&gt;callback URL を設定&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;ログインする際に &lt;code&gt;https://github.com/login/oauth/authorize?cleint_id=[cleint_id]&lt;/code&gt; へリダイレクトさせる
&lt;ul&gt;
&lt;li&gt;(1)の App の使用を許可するかという画面へ飛ぶ&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;許可すると(1)で設定した callback エンドポイントが叩かれる
&lt;ul&gt;
&lt;li&gt;code というリクエストパラメータがついてくる&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Client ID・Client Secret と(3)の code を使うことで bearer token が手に入る
&lt;ul&gt;
&lt;li&gt;このトークンを利用することで GitHub ユーザーの情報を取得したりできる&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;(4)を利用して取得した GitHub アカウント名などを Cookie に積んでおく&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;あとは (5) の Cookie の有無によってログイン済みかどうかを判断するだけ（まぁこれは GitHub App とか関係ないよくあるやり方）． つまり問題は Servant でどうやってログイン情報などを Cookie に載せるかということだ．&lt;/p&gt;
&lt;h2 id="servant-で認証機能"&gt;Servant で認証機能&lt;/h2&gt;
&lt;p&gt;を作るには &lt;a href="https://hackage.haskell.org/package/servant-auth-server"&gt;servant-auth-server&lt;/a&gt; という Servant 公式のパッケージを使えば良いようだ． 詳しくは以下の公式ドキュメントを読むと良い：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.servant.dev/en/stable/tutorial/Authentication.html"&gt;Authentication in Servant — Servant documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;servant-auth-server を利用することで，JWT エンコードした認証情報を Cookie として保存したり，その Cookie の有無によって認証済みかどうかチェックしたりなどができる． 公式ドキュメント以外に特に利用の仕方を解説した記事とか見当たらなくて，結局実装コード読んだり，servant-auth-server パッケージを使ってるリポジトリを GitHub で検索したりして手探りで実装していった．&lt;/p&gt;
&lt;h3 id="api-の型"&gt;API の型&lt;/h3&gt;
&lt;p&gt;元々はこんな感じ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Text.Blaze.Html5&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;H&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt;           &lt;span class="dt"&gt;Servant.HTML.Blaze&lt;/span&gt; (&lt;span class="dt"&gt;HTML&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;API&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Get&lt;/span&gt; &amp;#39;[&lt;span class="dt"&gt;HTML&lt;/span&gt;] &lt;span class="dt"&gt;H.Html&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;static&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Raw&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6"&gt;&lt;/a&gt;      &lt;span class="op"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;api&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Todo.CRUD&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これに認証機能を追加する：&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;API&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; (&lt;span class="dt"&gt;Auth&lt;/span&gt; &amp;#39;[&lt;span class="dt"&gt;Cookie&lt;/span&gt;] &lt;span class="dt"&gt;GitHub.User&lt;/span&gt; &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Protected&lt;/span&gt;) &lt;span class="op"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Unprotected&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Protected&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4"&gt;&lt;/a&gt;      &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;api&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Todo.CRUD&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Unprotected&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7"&gt;&lt;/a&gt;      &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Get&lt;/span&gt; &amp;#39;[&lt;span class="dt"&gt;HTML&lt;/span&gt;] &lt;span class="dt"&gt;H.Html&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8"&gt;&lt;/a&gt;   &lt;span class="op"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;static&amp;quot;&lt;/span&gt;   &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Raw&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9"&gt;&lt;/a&gt;   &lt;span class="op"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;login&amp;quot;&lt;/span&gt;    &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;GetRedirected&lt;/span&gt; &amp;#39;[]&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="#cb2-10"&gt;&lt;/a&gt;   &lt;span class="op"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;callback&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;QueryParam&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;code&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="op"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;GetRedirected&lt;/span&gt; &lt;span class="dt"&gt;JWTCookieHeaders&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="#cb2-11"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-12"&gt;&lt;a href="#cb2-12"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;GetRedirected&lt;/span&gt; headers &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-13"&gt;&lt;a href="#cb2-13"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;Verb&lt;/span&gt; &lt;span class="dt"&gt;&amp;#39;GET&lt;/span&gt; &lt;span class="dv"&gt;308&lt;/span&gt; &amp;#39;[&lt;span class="dt"&gt;HTML&lt;/span&gt;] (&lt;span class="dt"&gt;Headers&lt;/span&gt; (&lt;span class="dt"&gt;Header&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Location&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &amp;#39;&lt;span class="op"&gt;:&lt;/span&gt; headers) &lt;span class="dt"&gt;NoContent&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb2-14"&gt;&lt;a href="#cb2-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-15"&gt;&lt;a href="#cb2-15"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;JWTCookieHeaders&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-16"&gt;&lt;a href="#cb2-16"&gt;&lt;/a&gt;  &amp;#39;[ &lt;span class="dt"&gt;Header&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Set-Cookie&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;SetCookie&lt;/span&gt;, &lt;span class="dt"&gt;Header&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Set-Cookie&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;SetCookie&lt;/span&gt; ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Protected&lt;/code&gt; と &lt;code&gt;Unprotected&lt;/code&gt; 型のように，認証済みの場合だけ利用可能なエンドポイントとそうでないエンドポイントを分けると良いようだ． 今回は &lt;code&gt;/index.html&lt;/code&gt; を認証の外にしたが，別に中にしてもいいと思う． 認証側に &lt;code&gt;Auth &amp;#39;[Cookie] a&lt;/code&gt; を追加することで JWT エンコードされた Cookie の有無で認証済みかを判断し，Cookie があればそれを &lt;code&gt;a&lt;/code&gt; 型へデコードしてくれる． Cookie の付与自体は callback エンドポイントで行う． ちなみに，&lt;code&gt;Set-Cookie&lt;/code&gt; が2つあるのは，1つを CRSF Protection に使うためだ（CRSF Protection については後述）．&lt;/p&gt;
&lt;h3 id="cookie-と-jwt-の設定"&gt;Cookie と JWT の設定&lt;/h3&gt;
&lt;p&gt;また，Cookie や JWT の設定は Servant の Context 機能で渡す必要がある：&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;main ::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt;main &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;  todoDB       &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; STM.atomically &lt;span class="op"&gt;$&lt;/span&gt; STM.newTVar initTodoDB&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4"&gt;&lt;/a&gt;  clientId     &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; getEnv &lt;span class="st"&gt;&amp;quot;GITHUB_CLIENT_ID&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5"&gt;&lt;/a&gt;  clientSecret &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; getEnv &lt;span class="st"&gt;&amp;quot;GITHUB_CLIENT_SECRET&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6"&gt;&lt;/a&gt;  jwtSettings  &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; defaultJWTSettings &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; generateKey&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;let&lt;/span&gt; cfg   &lt;span class="ot"&gt;=&lt;/span&gt; cookieSettings &lt;span class="op"&gt;:.&lt;/span&gt; jwtSettings &lt;span class="op"&gt;:.&lt;/span&gt; &lt;span class="dt"&gt;EmptyContext&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8"&gt;&lt;/a&gt;      oauth &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;client_id &lt;span class="op"&gt;@=&lt;/span&gt; clientId &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;client_secret &lt;span class="op"&gt;@=&lt;/span&gt; clientSecret &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; nil&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9"&gt;&lt;/a&gt;      env   &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;index  &lt;span class="op"&gt;@=&lt;/span&gt; indexHtml&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10"&gt;&lt;/a&gt;           &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;cookie &lt;span class="op"&gt;@=&lt;/span&gt; cookieSettings&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11"&gt;&lt;/a&gt;           &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;jwt    &lt;span class="op"&gt;@=&lt;/span&gt; jwtSettings&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12"&gt;&lt;/a&gt;           &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;todos  &lt;span class="op"&gt;@=&lt;/span&gt; todoDB&lt;/span&gt;
&lt;span id="cb3-13"&gt;&lt;a href="#cb3-13"&gt;&lt;/a&gt;           &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;oauth  &lt;span class="op"&gt;@=&lt;/span&gt; oauth&lt;/span&gt;
&lt;span id="cb3-14"&gt;&lt;a href="#cb3-14"&gt;&lt;/a&gt;           &lt;span class="op"&gt;&amp;lt;:&lt;/span&gt; nil&lt;/span&gt;
&lt;span id="cb3-15"&gt;&lt;a href="#cb3-15"&gt;&lt;/a&gt;  Warp.run &lt;span class="dv"&gt;8080&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; serveWithContext api cfg (server env)&lt;/span&gt;
&lt;span id="cb3-16"&gt;&lt;a href="#cb3-16"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-17"&gt;&lt;a href="#cb3-17"&gt;&lt;/a&gt;  initTodoDB &lt;span class="ot"&gt;=&lt;/span&gt; (&lt;span class="fu"&gt;length&lt;/span&gt; initTodos, IntMap.fromList initTodos)&lt;/span&gt;
&lt;span id="cb3-18"&gt;&lt;a href="#cb3-18"&gt;&lt;/a&gt;  cookieSettings &lt;span class="ot"&gt;=&lt;/span&gt; defaultCookieSettings&lt;/span&gt;
&lt;span id="cb3-19"&gt;&lt;a href="#cb3-19"&gt;&lt;/a&gt;    { cookieIsSecure &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;NotSecure&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-20"&gt;&lt;a href="#cb3-20"&gt;&lt;/a&gt;    , cookieMaxAge &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; Time.secondsToDiffTime (&lt;span class="dv"&gt;3&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; &lt;span class="dv"&gt;60&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb3-21"&gt;&lt;a href="#cb3-21"&gt;&lt;/a&gt;    , cookieXsrfSetting &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-22"&gt;&lt;a href="#cb3-22"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb3-23"&gt;&lt;a href="#cb3-23"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-24"&gt;&lt;a href="#cb3-24"&gt;&lt;/a&gt;&lt;span class="ot"&gt;api ::&lt;/span&gt; &lt;span class="dt"&gt;Proxy&lt;/span&gt; (&lt;span class="dt"&gt;API&lt;/span&gt; &amp;#39;[&lt;span class="dt"&gt;Cookie&lt;/span&gt;])&lt;/span&gt;
&lt;span id="cb3-25"&gt;&lt;a href="#cb3-25"&gt;&lt;/a&gt;api &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Proxy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;それぞれの設定は servant-auth-server の &lt;code&gt;defaultCookieSettings&lt;/code&gt; と &lt;code&gt;defaultJWTSettings&lt;/code&gt; を利用すれば良い．&lt;/p&gt;
&lt;p&gt;今回は localhost で利用するようにしてるので &lt;code&gt;cookieIsSecure&lt;/code&gt; に &lt;code&gt;NotSecure&lt;/code&gt; を設定してる（これで HttpOnly になる）が，普通は &lt;code&gt;Secure&lt;/code&gt; のままで良い． &lt;code&gt;cookieXsrfSetting&lt;/code&gt; は前述した CSRF Protection の設定で，デフォルトではオンになっている． オンの場合は Cookie に設定された CSRF Protection 用のトークンをヘッダーに設定してリクエストしないと，Protected な API は弾かれるようになる（Cookie 名は cookieXsrfSetting で設定する）． ちなみに，GET リクエストは CSRF Protection しないという設定も可能だ．&lt;/p&gt;
&lt;p&gt;JWT の設定にはエンコードするための鍵を渡す必要がある． 今回は servant-auth-server の &lt;code&gt;generateKey&lt;/code&gt; 関数を利用している． これは（少なくともバージョン0.4.5.1では）256長の対称鍵（HS256）をランダムに生成してくれる． ランダムに生成したものを利用してるので，起動するたびに Cookie の情報が変わってしまう点に注意． もし，JWTのアルゴリズムや鍵を別のものにしたい場合は &lt;a href="http://hackage.haskell.org/package/jose"&gt;jose パッケージ&lt;/a&gt; を利用すれば良いはずだ．&lt;/p&gt;
&lt;h1 id="section"&gt;&lt;/h1&gt;
&lt;p&gt;余談だが，Cookie にある JWT のデコードは Servant Context の設定を利用するが，Cookie に積むときはエンドポイントの最後でエンコードをするので，同一の設定をエンドポイントまで橋渡しをしないといけない（ぼくは他方がデフォルトのままになってるのに気付かず3時間溶かした…）．&lt;/p&gt;
&lt;h3 id="protected-なエンドポイント"&gt;Protected なエンドポイント&lt;/h3&gt;
&lt;p&gt;こんな感じ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;protected ::&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;AuthResult&lt;/span&gt; &lt;span class="dt"&gt;GitHub.User&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Server&lt;/span&gt; &lt;span class="dt"&gt;Protected&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2"&gt;&lt;/a&gt;protected env (&lt;span class="dt"&gt;Authenticated&lt;/span&gt; _) &lt;span class="ot"&gt;=&lt;/span&gt; todoAPI (env &lt;span class="op"&gt;^.&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;todos)&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3"&gt;&lt;/a&gt;protected _ _                   &lt;span class="ot"&gt;=&lt;/span&gt; throwAll err401&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;今回はアカウントによってレスポンスの出しわけをしてないので，&lt;code&gt;Authenticated&lt;/code&gt; かどうかだけをみている．&lt;/p&gt;
&lt;h3 id="ログインエンドポイント"&gt;ログインエンドポイント&lt;/h3&gt;
&lt;p&gt;ログインエンドポイントはただ GitHub の該当 URL へリダイレクトするだけ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;unprotected ::&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Server&lt;/span&gt; &lt;span class="dt"&gt;Unprotected&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2"&gt;&lt;/a&gt;unprotected env &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;pure&lt;/span&gt; (env &lt;span class="op"&gt;^.&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;index) &lt;span class="op"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; serveDirectoryFileServer &lt;span class="st"&gt;&amp;quot;static&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; login &lt;span class="op"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; callback&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5"&gt;&lt;/a&gt;    login &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; addHeader (GitHub.authorizeUrl &lt;span class="op"&gt;$&lt;/span&gt; env &lt;span class="op"&gt;^.&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;oauth) &lt;span class="dt"&gt;NoContent&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6"&gt;&lt;/a&gt;    callback &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;undefined&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- GitHub module&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9"&gt;&lt;/a&gt;&lt;span class="ot"&gt;authorizeUrl ::&lt;/span&gt; &lt;span class="dt"&gt;OAuthSettings&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;OAuthSettings&lt;/code&gt; は GitHub App の Client ID と Client Secret が保存されている．&lt;/p&gt;
&lt;h3 id="callback-エンドポイント"&gt;callback エンドポイント&lt;/h3&gt;
&lt;p&gt;最後は callback で，JWT エンコードした認証情報を Cookie に保存すれば良い：&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;unprotected ::&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Server&lt;/span&gt; &lt;span class="dt"&gt;Unprotected&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2"&gt;&lt;/a&gt;unprotected env &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4"&gt;&lt;/a&gt;    login &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5"&gt;&lt;/a&gt;    callback (&lt;span class="dt"&gt;Just&lt;/span&gt; code) &lt;span class="ot"&gt;=&lt;/span&gt; GitHub.fetchUser (env &lt;span class="op"&gt;^.&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;oauth) code &lt;span class="op"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-6"&gt;&lt;a href="#cb6-6"&gt;&lt;/a&gt;      &lt;span class="dt"&gt;Nothing&lt;/span&gt;   &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; throwError err401&lt;/span&gt;
&lt;span id="cb6-7"&gt;&lt;a href="#cb6-7"&gt;&lt;/a&gt;      &lt;span class="dt"&gt;Just&lt;/span&gt; user &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; liftIO (acceptLogin (env &lt;span class="op"&gt;^.&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;cookie) (env &lt;span class="op"&gt;^.&lt;/span&gt; &lt;span class="op"&gt;#&lt;/span&gt;jwt) user) &lt;span class="op"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-8"&gt;&lt;a href="#cb6-8"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Nothing&lt;/span&gt;           &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; throwError err401&lt;/span&gt;
&lt;span id="cb6-9"&gt;&lt;a href="#cb6-9"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Just&lt;/span&gt; applyCookies &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; addHeader &lt;span class="st"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; (applyCookies &lt;span class="dt"&gt;NoContent&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb6-10"&gt;&lt;a href="#cb6-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-11"&gt;&lt;a href="#cb6-11"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- GitHub module&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-12"&gt;&lt;a href="#cb6-12"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fetchUser ::&lt;/span&gt; &lt;span class="dt"&gt;MonadIO&lt;/span&gt; m &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;OAuthSettings&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; m (&lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;認証情報には GitHub のユーザー情報を利用しており，callback で渡された &lt;code&gt;code&lt;/code&gt; パラメーターを利用して（取得したトークンを利用して）取得する． 認証情報を JWT エンコードして Cookie に埋め込む処理は servant-auth-servar パッケージの &lt;code&gt;acceptLogin&lt;/code&gt; 関数を使うだけで良い．&lt;/p&gt;
&lt;h1 id="section-1"&gt;&lt;/h1&gt;
&lt;p&gt;これで API 側の準備はできた． あとはフロントを少しいじって出来上がり．&lt;/p&gt;
&lt;h2 id="フロントにログインボタンを作る"&gt;フロントにログインボタンを作る&lt;/h2&gt;
&lt;p&gt;認証状態を使ってイロイロと出し分けたほうがいいのだが，めんどくさいのでただ &lt;code&gt;/login&lt;/code&gt; へのリンクをおいた：&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;view&lt;/span&gt; : &lt;span class="dt"&gt;Model&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Html&lt;/span&gt; &lt;span class="dt"&gt;Msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2"&gt;&lt;/a&gt;&lt;span class="fu"&gt;view&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;div&lt;/span&gt; [ &lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;my-3 mx-auto col-10&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4"&gt;&lt;/a&gt;        [ &lt;span class="fu"&gt;h1&lt;/span&gt; [] [ &lt;span class="fu"&gt;text&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;ToDo List !!&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;loginButton&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;viewToDos&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;viewPost&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="#cb7-7"&gt;&lt;/a&gt;        ]&lt;/span&gt;
&lt;span id="cb7-8"&gt;&lt;a href="#cb7-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-9"&gt;&lt;a href="#cb7-9"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-10"&gt;&lt;a href="#cb7-10"&gt;&lt;/a&gt;&lt;span class="fu"&gt;loginButton&lt;/span&gt; : &lt;span class="dt"&gt;Html&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-11"&gt;&lt;a href="#cb7-11"&gt;&lt;/a&gt;&lt;span class="fu"&gt;loginButton&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-12"&gt;&lt;a href="#cb7-12"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;button&lt;/span&gt; [ &lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;btn btn-sm btn-outline float-right mt-2&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;type_&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;button&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb7-13"&gt;&lt;a href="#cb7-13"&gt;&lt;/a&gt;        [ &lt;span class="fu"&gt;a&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-14"&gt;&lt;a href="#cb7-14"&gt;&lt;/a&gt;            [ &lt;span class="fu"&gt;href&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;/login&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-15"&gt;&lt;a href="#cb7-15"&gt;&lt;/a&gt;            &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;style&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;color&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;inherit&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-16"&gt;&lt;a href="#cb7-16"&gt;&lt;/a&gt;            &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;style&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;text-decoration-line&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;none&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-17"&gt;&lt;a href="#cb7-17"&gt;&lt;/a&gt;            ]&lt;/span&gt;
&lt;span id="cb7-18"&gt;&lt;a href="#cb7-18"&gt;&lt;/a&gt;            [ &lt;span class="fu"&gt;text&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Login by GitHub&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb7-19"&gt;&lt;a href="#cb7-19"&gt;&lt;/a&gt;        ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;こんな感じ：&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/servant-auth-with-github-apps/sample.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;h2 id="おまけreaderモナド"&gt;おまけ：Readerモナド&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Env&lt;/code&gt; は Cookie や JWT の設定を保持しているグローバル環境型だ． こういうのは引数としてリレーしても良いが，&lt;code&gt;Reader&lt;/code&gt; モナド使って渡すのがよくある手法だ． Servant の場合は &lt;a href="https://hackage.haskell.org/package/servant-server-0.17/docs/Servant-Server.html#v:hoistServerWithContext"&gt;&lt;code&gt;hoistServerWithContext&lt;/code&gt;&lt;/a&gt; を使うことで &lt;code&gt;Handler&lt;/code&gt; の代わりに別のモナドを利用できる：&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;main ::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2"&gt;&lt;/a&gt;main &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3"&gt;&lt;/a&gt;  &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4"&gt;&lt;/a&gt;  Warp.run &lt;span class="dv"&gt;8080&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5"&gt;&lt;/a&gt;    serveWithContext api cfg (hoistServerWithContext api ctx (convert env) server)&lt;/span&gt;
&lt;span id="cb8-6"&gt;&lt;a href="#cb8-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-7"&gt;&lt;a href="#cb8-7"&gt;&lt;/a&gt;&lt;span class="ot"&gt;ctx ::&lt;/span&gt; &lt;span class="dt"&gt;Proxy&lt;/span&gt; &amp;#39;[ &lt;span class="dt"&gt;CookieSettings&lt;/span&gt;, &lt;span class="dt"&gt;JWTSettings&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb8-8"&gt;&lt;a href="#cb8-8"&gt;&lt;/a&gt;ctx &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Proxy&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-9"&gt;&lt;a href="#cb8-9"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-10"&gt;&lt;a href="#cb8-10"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;App&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;ReaderT&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="dt"&gt;Handler&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-11"&gt;&lt;a href="#cb8-11"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-12"&gt;&lt;a href="#cb8-12"&gt;&lt;/a&gt;&lt;span class="ot"&gt;convert ::&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;App&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Handler&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb8-13"&gt;&lt;a href="#cb8-13"&gt;&lt;/a&gt;convert context app &lt;span class="ot"&gt;=&lt;/span&gt; runReaderT app context&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;あとは &lt;code&gt;Env -&amp;gt; Server api&lt;/code&gt; みたいな型を &lt;code&gt;ServerT api App&lt;/code&gt; としていくだけ．&lt;/p&gt;
&lt;h2 id="おしまい"&gt;おしまい&lt;/h2&gt;
&lt;p&gt;意外とこういう組み合わせに言及した記事がなくて調べるの大変だった． あと一応，実アプリケーションで使うときはちゃんと安全性について別途調べてくださいね（責任は持ちません）．&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>https://matsubara0507.github.io/posts/2020-04-01-update-dependencies-with-lts15.html</id><title type="text">git-plantation の依存パッケージのバージョンアゲアゲ with LTS-15</title><updated>2020-04-01T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2020-04-01-update-dependencies-with-lts15.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;自作している git-plantation という Haskell アプリケーションの依存パッケージのバージョンを、Stackage LTS-15 でビルドできるようにバージョンを色々とあげました． 本記事はそのメモ書きです（記事にするほどのことではないんだけど，思ったより色々したので忘れそうだから記事にした笑）．&lt;/p&gt;
&lt;p&gt;ちなみに git-plantation については，&lt;a href="https://www.slideshare.net/noob00/haskell-191796924"&gt;このスライド&lt;/a&gt;を参照してください． いくつかのパッケージをフォークしたり，ラッパーパッケージを作ったり，そもそも自作したりしてるのでタイミングによっては LTS のメジャーバージョンを一つ上げるだけでも結構大変なのです．&lt;/p&gt;
&lt;h2 id="ハイライト"&gt;ハイライト&lt;/h2&gt;
&lt;p&gt;ちなみに，元々は LTS 14 だった&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GHC のバージョンが 8.8.3 になる（影響はさほどない）&lt;/li&gt;
&lt;li&gt;extensible を 0.8 にする&lt;/li&gt;
&lt;li&gt;github を 0.25 にする&lt;/li&gt;
&lt;li&gt;servant-elm を 0.7.1 にする（これもさほど影響はない）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://github.com/matsubara0507/git-plantation/pull/58"&gt;最終的なPRはこれ&lt;/a&gt;．&lt;/p&gt;
&lt;h2 id="extensible-0.8"&gt;extensible-0.8&lt;/h2&gt;
&lt;p&gt;0.8 ではもともと deprecated になっていた関数や型がついに消えたので，利用しっぱなしだったコードがビルドできなくなった：&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt; &lt;span class="ex"&gt;/.../drone-1.0.1/src/Drone/Types&lt;/span&gt;/Cron.hs:&lt;span class="ex"&gt;25&lt;/span&gt;:44: error:&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2"&gt;&lt;/a&gt;     &lt;span class="ex"&gt;Not&lt;/span&gt; in scope: type constructor or class ‘:*’&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3"&gt;&lt;/a&gt;     &lt;span class="ex"&gt;Perhaps&lt;/span&gt; you meant one of these:&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4"&gt;&lt;/a&gt;       ‘:&lt;span class="kw"&gt;&amp;amp;&lt;/span&gt;’ &lt;span class="kw"&gt;(&lt;/span&gt;&lt;span class="ex"&gt;imported&lt;/span&gt; from Data.Extensible&lt;span class="kw"&gt;)&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5"&gt;&lt;/a&gt;       ‘:/’ &lt;span class="kw"&gt;(&lt;/span&gt;&lt;span class="ex"&gt;imported&lt;/span&gt; from Data.Extensible&lt;span class="kw"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;|&lt;/span&gt;                  &lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7"&gt;&lt;/a&gt; &lt;span class="ex"&gt;25&lt;/span&gt; &lt;span class="kw"&gt;|&lt;/span&gt; &lt;span class="bu"&gt;type&lt;/span&gt; CronPatch = Nullable (Field Identity) &lt;span class="bu"&gt;:&lt;/span&gt;* CronPatchFields&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;|&lt;/span&gt;                                            ^^&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;消えたのはこれら&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Associate k v xs&lt;/code&gt; =&amp;gt; &lt;code&gt;Lookup xs k v&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;h :* xs&lt;/code&gt; =&amp;gt; &lt;code&gt;xs :&amp;amp; h&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;h :| xs&lt;/code&gt; =&amp;gt; &lt;code&gt;xs :/ h&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AssocKey kv&lt;/code&gt; =&amp;gt; &lt;code&gt;KeyOf kv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AssocValue kv&lt;/code&gt; =&amp;gt; &lt;code&gt;TargetOf kv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ValueIs&lt;/code&gt; =&amp;gt; &lt;code&gt;TargetIs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;KeyValue&lt;/code&gt; =&amp;gt; &lt;code&gt;KeyTargetAre&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;proxyAssocKey&lt;/code&gt; =&amp;gt; &lt;code&gt;proxyKeyOf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;proxyAssocValue&lt;/code&gt; =&amp;gt; &lt;code&gt;proxyTargetOf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stringAssocKey&lt;/code&gt; =&amp;gt; &lt;code&gt;stringKeyOf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;訊&lt;/code&gt; =&amp;gt; &lt;code&gt;xlb&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上3つは演算子の順番が変わってる点に注意． 他はただ名前を変えただけ（&lt;code&gt;Associate&lt;/code&gt; の名前が変わったためかしら？）．&lt;/p&gt;
&lt;h2 id="github-0.25"&gt;github-0.25&lt;/h2&gt;
&lt;p&gt;github パッケージは 0.24 でかなり大きなインターフェースの刷新をしており，その影響がデカかった． 今までは一つの API に対して最大3つの関数が用意されていた：&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- https://developer.github.com/v3/users/#get-a-single-user の関数&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;&lt;span class="ot"&gt;userInfoFor ::&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Either&lt;/span&gt; &lt;span class="dt"&gt;Error&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;&lt;span class="ot"&gt;userInfoFor&amp;#39; ::&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Auth&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Either&lt;/span&gt; &lt;span class="dt"&gt;Error&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4"&gt;&lt;/a&gt;&lt;span class="ot"&gt;userInfoForR ::&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Request&lt;/span&gt; k &lt;span class="dt"&gt;User&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ベースは &lt;code&gt;hogeR&lt;/code&gt; 関数で，他はこの関数のラッパー関数だ． 0.24 からは &lt;code&gt;hogeR&lt;/code&gt; 関数だけ残して他の関数は廃止し，&lt;code&gt;github&lt;/code&gt; と &lt;code&gt;github&amp;#39;&lt;/code&gt; の2つの関数を用意した：&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- だいたいこういう対応&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt;userInfoFor name &lt;span class="ot"&gt;=&lt;/span&gt; github&amp;#39; (userInfoForR name)&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;userInfoFor&amp;#39; (&lt;span class="dt"&gt;Just&lt;/span&gt; auth) name &lt;span class="ot"&gt;=&lt;/span&gt; github auth (userInfoForR name)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;また，github パッケージはフォークして足りない API 関数を足して利用していたため，それらの修正（というか &lt;code&gt;hogeR&lt;/code&gt; 以外の削除）をする必要があった． 追加してたけどフォーク元に PR を投げてなかったのはこれらの関数（完全にメモ）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;removeCollaborator&lt;/code&gt; : リポジトリのコラボレーターの削除&lt;/li&gt;
&lt;li&gt;&lt;code&gt;teamInfoByName&lt;/code&gt; : Organization のチームをチーム名から引く&lt;/li&gt;
&lt;li&gt;&lt;code&gt;addOrUpdateMembership&lt;/code&gt; : Organization メンバーの権限の追加ないしは変更&lt;/li&gt;
&lt;li&gt;&lt;code&gt;removeMembership&lt;/code&gt; : Organization メンバーの権限の削除&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="servant-elm-0.7.1"&gt;servant-elm-0.7.1&lt;/h2&gt;
&lt;p&gt;ビルドが通らないことはないが生成ファイルが変わったので，念のため差分をチェックした． 少なくとも僕の生成コードに影響があったのは&lt;a href="https://github.com/haskell-servant/servant-elm/pull/59"&gt;この PR&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Using the appropriate toString functions for different types&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;要するに，デフォルトで定義しているデータ型以外の型で文字列からJSONデコードするときの振る舞いを自分で定義したいって感じだと思う． たぶん．&lt;/p&gt;
&lt;h1 id="section"&gt;&lt;/h1&gt;
&lt;p&gt;servant-elm は elmap.hs というのでラップしてるのでそっちのアップデートも行った． こっちには生成コードのテストも追加してあるので&lt;a href="https://github.com/matsubara0507/elmap.hs/pull/1/files#diff-3e612857d13f467c108121bba96a6232"&gt;差分がわかりやすい&lt;/a&gt;．&lt;/p&gt;
&lt;h2 id="おしまい"&gt;おしまい&lt;/h2&gt;
&lt;p&gt;他にも CI/CD を GitHub Actions にしたりした．&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/03/22/213946</id><title type="text">rustでdiscordのbotを作ってみたくて下調べ(4)</title><updated>2020-03-22T21:40:51+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/03/22/213946"/><summary type="html">rustでdiscordのbotを作ってみたくて下調べ(3) - 北海道苫小牧市出身の初老PGが書くブログ で serenity を紹介したが、最近 async版 の開発が進んでいる。試してみたが、まともに動くようだ。ベンチマークなど取っていないので、 async にする価値があるのかはよくわかっていないが、 Rust の async/await を使ってなにか作ってみたいというのがもともとのモチベーションなので、これを使ってみることにする。まだ PR の段階でマージされるまではしばらくかかりそうなので、利用したければ Cargo.toml へ以下のように書く。 [dependencies.s…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/03/08/212048</id><title type="text">impl Trait 型の値を再代入しようとしてハマった</title><updated>2020-03-08T21:20:48+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/03/08/212048"/><summary type="html">impl トレイト名 は Rust で存在型を扱うのに使える 。しかし、以下はコンパイルが通らない。 use std::fmt::Display; fn f&lt;T&gt;(t: T) -&gt; impl Display where T: Display, { t } fn main() { let mut s = f(""); s = f(s); } Compiling playground v0.0.1 (/playground) error[E0308]: mismatched types --&gt; src/lib.rs:12:11 | 12 | s = f(s); | ^ expected `&amp;str…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/03/07/%E6%96%B0%E3%81%97%E3%81%84%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%83%BC</id><title type="text">新しいディスプレー</title><updated>2020-03-07T01:22:14+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/03/07/%E6%96%B0%E3%81%97%E3%81%84%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%83%BC"/><summary type="html">会社が 4K ディスプレーなのもあって、家でプログラミングしてたら画面が窮屈に感じてきてうちも 4K ディスプレーを導入しました。 特に Elm の標準のフォーマットが密度低いのでフル HD だと不便だったのが最後の引き金でした。 4K かつ HDR にしました。 KEIAN 28インチ4K対応LEDモニター KWIN28 ゲーミングモニター発売日: 2019/04/20メディア: Personal Computers 4K で High DPI 設定による高精細は言わずもがな HDR も綺麗ですね。 綺麗なんだけど Windows で HDR 出力をオンにしたときの SDR（今までのダイナミ…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2020/03/03/100000</id><title type="text">HomebrewのインストーラーをRubyからBashに書き直しました！</title><updated>2020-03-03T10:35:39+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2020/03/03/100000"/><summary type="html">みなさんはHomebrewをお使いでしょうか。macOSをお使いの多くの開発者が使っていると思います。 HomebrewのインストーラーはRubyで書かれており、次のコマンドでインストールするようになっていました。 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" HomebrewがRubyに依存していることは良いのですが (formulaの書きやすさはRubyならでは)、インストーラーの話になると事情が変わってきます。Homebrewのインストー…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2020-02-10-elm-github-oauth2-sample.html</id><title type="text">Elm + GitHub OAuth 2.0 (Firebase) のサンプルプログラムを書いてみた</title><updated>2020-02-10T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2020-02-10-elm-github-oauth2-sample.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;とあるアプリケーションに Elm + GitHub OAuth 2.0 を使ってみたいなと思い，その練習用のアプリケーションを作ってみました：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/matsubara0507/elm-github-oauth2-sample"&gt;matsubara0507/elm-github-oauth2-sample - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;サンプルのために認可用のサーバーを用意するのがめんどくさかったので，近年話題の Firebase の Authorization 機能を利用することにしました．&lt;/p&gt;
&lt;h2 id="作ったアプリケーション"&gt;作ったアプリケーション&lt;/h2&gt;
&lt;p&gt;作成した SPA は &lt;a href="https://matsubara0507.github.io/elm-github-oauth2-sample"&gt;GitHub Pages&lt;/a&gt; に置いてある． ログインっぽいボタンを押すと Firebase Authorization を介して，GitHub OAuth 2.0 での認可がされる． もちろん，もともと試したかったことはここまでだが，認可しておしまいだと味気がない． なので：&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;認可時に GitHub OAuth トークンを取得&lt;/li&gt;
&lt;li&gt;トークンを使ってログインしたユーザーの公開リポジトリの情報を取得&lt;/li&gt;
&lt;li&gt;リポジトリのスター数を使ってユーザーのステータスをリッチに描写する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;色々試して最終的にこんな感じ：&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/elm-github-oauth2-sample/page.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;ちょっとやりすぎた．&lt;/p&gt;
&lt;h2 id="実装する"&gt;実装する&lt;/h2&gt;
&lt;p&gt;やったことは3ステップ&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;Elm と Firebase を繋ぐ&lt;/li&gt;
&lt;li&gt;リポジトリを取得（GraphQL）&lt;/li&gt;
&lt;li&gt;円グラフを描写&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;2と3は完全におまけですね．&lt;/p&gt;
&lt;h3 id="elm-と-firebase"&gt;Elm と Firebase&lt;/h3&gt;
&lt;p&gt;まずは Firebase を準備する． &lt;a href="https://firebase.google.com/docs/auth/web/github-auth?hl=ja"&gt;公式サイトの手順&lt;/a&gt;がしっかりしてるので，それに習って準備する（GitHub App の設定とか）． プロバイダ（今回は GitHub）の設定と JavaScript のアプリの設定をすると「コレをコピペしてね」っていう設定とかが出てくる． コレを index.html と index.js に書いておく：&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode html"&gt;&lt;code class="sourceCode html"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2"&gt;&lt;/a&gt;&lt;span class="dt"&gt;&amp;lt;!doctype &lt;/span&gt;html&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;&amp;lt;meta&lt;/span&gt;&lt;span class="ot"&gt; http-equiv=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;content-type&amp;quot;&lt;/span&gt;&lt;span class="ot"&gt; charset=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="kw"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;&amp;lt;link&lt;/span&gt;&lt;span class="ot"&gt; rel=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt;&lt;span class="ot"&gt; href=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;https://unpkg.com/@primer/css@14.2.0/dist/primer.css&amp;quot;&lt;/span&gt;&lt;span class="kw"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8"&gt;&lt;/a&gt;&lt;span class="kw"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-9"&gt;&lt;a href="#cb1-9"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;&amp;lt;div&lt;/span&gt;&lt;span class="ot"&gt; id=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;elm-node&amp;quot;&lt;/span&gt;&lt;span class="kw"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-10"&gt;&lt;a href="#cb1-10"&gt;&lt;/a&gt;  &lt;span class="co"&gt;&amp;lt;!-- firebase-app と firebase-auth が必要 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-11"&gt;&lt;a href="#cb1-11"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="ot"&gt; src=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;https://www.gstatic.com/firebasejs/7.8.1/firebase-app.js&amp;quot;&lt;/span&gt;&lt;span class="kw"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-12"&gt;&lt;a href="#cb1-12"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="ot"&gt; src=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;https://www.gstatic.com/firebasejs/7.8.1/firebase-auth.js&amp;quot;&lt;/span&gt;&lt;span class="kw"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-13"&gt;&lt;a href="#cb1-13"&gt;&lt;/a&gt;  &lt;span class="co"&gt;&amp;lt;!-- static/main.js は Elm からあとで生成する --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-14"&gt;&lt;a href="#cb1-14"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="ot"&gt; src=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;static/main.js&amp;quot;&lt;/span&gt;&lt;span class="kw"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-15"&gt;&lt;a href="#cb1-15"&gt;&lt;/a&gt;  &lt;span class="co"&gt;&amp;lt;!-- static/index.js は下記 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-16"&gt;&lt;a href="#cb1-16"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="ot"&gt; src=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;static/index.js&amp;quot;&lt;/span&gt;&lt;span class="kw"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-17"&gt;&lt;a href="#cb1-17"&gt;&lt;/a&gt;&lt;span class="kw"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-18"&gt;&lt;a href="#cb1-18"&gt;&lt;/a&gt;&lt;span class="kw"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode js"&gt;&lt;code class="sourceCode javascript"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;// static/index.js&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4"&gt;&lt;/a&gt;&lt;span class="co"&gt;// コレらの設定は公開してもいいらしいけど&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;var&lt;/span&gt; firebaseConfig &lt;span class="op"&gt;=&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;apiKey&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;...&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;authDomain&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;...&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;databaseURL&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;...&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;projectId&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;...&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="#cb2-10"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;storageBucket&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;...&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="#cb2-11"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;messagingSenderId&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;...&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-12"&gt;&lt;a href="#cb2-12"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;appId&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;...&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-13"&gt;&lt;a href="#cb2-13"&gt;&lt;/a&gt;}&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-14"&gt;&lt;a href="#cb2-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-15"&gt;&lt;a href="#cb2-15"&gt;&lt;/a&gt;firebase&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;initializeApp&lt;/span&gt;(firebaseConfig)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-16"&gt;&lt;a href="#cb2-16"&gt;&lt;/a&gt;&lt;span class="kw"&gt;const&lt;/span&gt; provider &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; firebase&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;auth&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;GithubAuthProvider&lt;/span&gt;()&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;あとは Elm から Firebase のメソッドを呼び出す． 基本的にコレを参考にした：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://qiita.com/ababup1192/items/f27f9af282d9fa642eb5"&gt;Elm portsでFirebase Firestoreを触ろう！ - Qiita&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Elm 用の Firebase パッケージ的なのはないので，Elm のポート機能を使って繋ぎ込む：&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;port&lt;/span&gt; &lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Firebase&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="op"&gt;..&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Json&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Encode&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;E&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;port&lt;/span&gt; &lt;span class="fu"&gt;signIn&lt;/span&gt; : () &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Cmd&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;port&lt;/span&gt; &lt;span class="fu"&gt;getSignInResult&lt;/span&gt; : () &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Cmd&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;port&lt;/span&gt; &lt;span class="fu"&gt;signedIn&lt;/span&gt; : (&lt;span class="dt"&gt;E&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Value&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Sub&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode js"&gt;&lt;code class="sourceCode javascript"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;// static/index.js&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2"&gt;&lt;/a&gt;&lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;const&lt;/span&gt; app &lt;span class="op"&gt;=&lt;/span&gt; Elm&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;Main&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;init&lt;/span&gt;(&lt;/span&gt;
&lt;span id="cb4-5"&gt;&lt;a href="#cb4-5"&gt;&lt;/a&gt;  { &lt;span class="dt"&gt;node&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="bu"&gt;document&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;getElementById&lt;/span&gt;(&lt;span class="st"&gt;&amp;#39;main&amp;#39;&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb4-6"&gt;&lt;a href="#cb4-6"&gt;&lt;/a&gt;  &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;flags&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; {}&lt;/span&gt;
&lt;span id="cb4-7"&gt;&lt;a href="#cb4-7"&gt;&lt;/a&gt;  }&lt;/span&gt;
&lt;span id="cb4-8"&gt;&lt;a href="#cb4-8"&gt;&lt;/a&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-9"&gt;&lt;a href="#cb4-9"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-10"&gt;&lt;a href="#cb4-10"&gt;&lt;/a&gt;app&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;ports&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;signIn&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;subscribe&lt;/span&gt;(_ &lt;span class="kw"&gt;=&amp;gt;&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb4-11"&gt;&lt;a href="#cb4-11"&gt;&lt;/a&gt;  &lt;span class="co"&gt;// popup の方はモバイル系でうまく動作しなかったのでこっちを使う&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-12"&gt;&lt;a href="#cb4-12"&gt;&lt;/a&gt;  firebase&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;auth&lt;/span&gt;()&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;signInWithRedirect&lt;/span&gt;(provider)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-13"&gt;&lt;a href="#cb4-13"&gt;&lt;/a&gt;})&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-14"&gt;&lt;a href="#cb4-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-15"&gt;&lt;a href="#cb4-15"&gt;&lt;/a&gt;app&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;ports&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;getSignInResult&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;subscribe&lt;/span&gt;(_ &lt;span class="kw"&gt;=&amp;gt;&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb4-16"&gt;&lt;a href="#cb4-16"&gt;&lt;/a&gt;  firebase&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;auth&lt;/span&gt;()&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;getRedirectResult&lt;/span&gt;()&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;then&lt;/span&gt;(&lt;span class="kw"&gt;function&lt;/span&gt;(result) {&lt;/span&gt;
&lt;span id="cb4-17"&gt;&lt;a href="#cb4-17"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;if&lt;/span&gt; (result&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;credential&lt;/span&gt;) {&lt;/span&gt;
&lt;span id="cb4-18"&gt;&lt;a href="#cb4-18"&gt;&lt;/a&gt;      app&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;ports&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;signedIn&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;send&lt;/span&gt;(result)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-19"&gt;&lt;a href="#cb4-19"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb4-20"&gt;&lt;a href="#cb4-20"&gt;&lt;/a&gt;  })&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;catch&lt;/span&gt;(&lt;span class="kw"&gt;function&lt;/span&gt;(error) {&lt;/span&gt;
&lt;span id="cb4-21"&gt;&lt;a href="#cb4-21"&gt;&lt;/a&gt;    app&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;ports&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="at"&gt;failSignIn&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;send&lt;/span&gt;(error)&lt;/span&gt;
&lt;span id="cb4-22"&gt;&lt;a href="#cb4-22"&gt;&lt;/a&gt;  })&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-23"&gt;&lt;a href="#cb4-23"&gt;&lt;/a&gt;})&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;繋ぎ込みはできた． サクッとトークンだけもらって，GitHub API v3 からユーザー名を取得する部分を実装する：&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="op"&gt;..&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Http&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Json&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Decode&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="dt"&gt;Decoder&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Json&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Encode&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;E&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Token&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Token&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9"&gt;&lt;/a&gt;&lt;span class="fu"&gt;tokenDecoder&lt;/span&gt; : &lt;span class="dt"&gt;Decoder&lt;/span&gt; &lt;span class="dt"&gt;Token&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-10"&gt;&lt;a href="#cb5-10"&gt;&lt;/a&gt;&lt;span class="fu"&gt;tokenDecoder&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; &lt;span class="dt"&gt;Token&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;string&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-11"&gt;&lt;a href="#cb5-11"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-12"&gt;&lt;a href="#cb5-12"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-13"&gt;&lt;a href="#cb5-13"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;login&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-14"&gt;&lt;a href="#cb5-14"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;name&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-15"&gt;&lt;a href="#cb5-15"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb5-16"&gt;&lt;a href="#cb5-16"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-17"&gt;&lt;a href="#cb5-17"&gt;&lt;/a&gt;&lt;span class="fu"&gt;getUserInfo&lt;/span&gt; : (&lt;span class="dt"&gt;Result&lt;/span&gt; &lt;span class="dt"&gt;Http&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Error&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Token&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Cmd&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-18"&gt;&lt;a href="#cb5-18"&gt;&lt;/a&gt;&lt;span class="fu"&gt;getUserInfo&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt; (&lt;span class="dt"&gt;Token&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt;) &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- 割愛&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;port&lt;/span&gt; &lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Firebase&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="op"&gt;..&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Json&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Decode&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="dt"&gt;Decoder&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-6"&gt;&lt;a href="#cb6-6"&gt;&lt;/a&gt;&lt;span class="fu"&gt;decoder&lt;/span&gt; : &lt;span class="dt"&gt;Decoder&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Token&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-7"&gt;&lt;a href="#cb6-7"&gt;&lt;/a&gt;&lt;span class="fu"&gt;decoder&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; &lt;span class="fu"&gt;identity&lt;/span&gt; (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;at&lt;/span&gt; [ &lt;span class="st"&gt;&amp;quot;credential&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;accessToken&amp;quot;&lt;/span&gt; ] &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;tokenDecoder&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb6-8"&gt;&lt;a href="#cb6-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-9"&gt;&lt;a href="#cb6-9"&gt;&lt;/a&gt;&lt;span class="fu"&gt;signedInWithDecode&lt;/span&gt; : (&lt;span class="dt"&gt;Result&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Error&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Token&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Sub&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-10"&gt;&lt;a href="#cb6-10"&gt;&lt;/a&gt;&lt;span class="fu"&gt;signedInWithDecode&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;signedIn&lt;/span&gt; (&lt;span class="fu"&gt;msg&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;decodeValue&lt;/span&gt; &lt;span class="fu"&gt;decoder&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;あとは適当に &lt;code&gt;Main&lt;/code&gt; から呼び出すだけ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Main&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="fu"&gt;main&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- import は割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4"&gt;&lt;/a&gt;&lt;span class="fu"&gt;main&lt;/span&gt; : &lt;span class="dt"&gt;Program&lt;/span&gt; () &lt;span class="dt"&gt;Model&lt;/span&gt; &lt;span class="dt"&gt;Msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5"&gt;&lt;/a&gt;&lt;span class="fu"&gt;main&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Browser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;application&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="#cb7-7"&gt;&lt;/a&gt;        { &lt;span class="fu"&gt;init&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;init&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-8"&gt;&lt;a href="#cb7-8"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;view&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;view&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-9"&gt;&lt;a href="#cb7-9"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;update&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;update&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-10"&gt;&lt;a href="#cb7-10"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;subscriptions&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Firebase&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;signedInWithDecode&lt;/span&gt; &lt;span class="dt"&gt;SignedIn&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-11"&gt;&lt;a href="#cb7-11"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;onUrlRequest&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;LinkClicked&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-12"&gt;&lt;a href="#cb7-12"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;onUrlChange&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;UrlChanged&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-13"&gt;&lt;a href="#cb7-13"&gt;&lt;/a&gt;        }&lt;/span&gt;
&lt;span id="cb7-14"&gt;&lt;a href="#cb7-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-15"&gt;&lt;a href="#cb7-15"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;Model&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-16"&gt;&lt;a href="#cb7-16"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;token&lt;/span&gt; : &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Token&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-17"&gt;&lt;a href="#cb7-17"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt; : &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;User&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-18"&gt;&lt;a href="#cb7-18"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;error&lt;/span&gt; : &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-19"&gt;&lt;a href="#cb7-19"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;key&lt;/span&gt; : &lt;span class="dt"&gt;Nav&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Key&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-20"&gt;&lt;a href="#cb7-20"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb7-21"&gt;&lt;a href="#cb7-21"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-22"&gt;&lt;a href="#cb7-22"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-23"&gt;&lt;a href="#cb7-23"&gt;&lt;/a&gt;    &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;LinkClicked&lt;/span&gt; &lt;span class="dt"&gt;Browser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;UrlRequest&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-24"&gt;&lt;a href="#cb7-24"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;UrlChanged&lt;/span&gt; &lt;span class="dt"&gt;Url&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-25"&gt;&lt;a href="#cb7-25"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;SignIn&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-26"&gt;&lt;a href="#cb7-26"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;SignedIn&lt;/span&gt; (&lt;span class="dt"&gt;Result&lt;/span&gt; &lt;span class="dt"&gt;Json&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Error&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Token&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb7-27"&gt;&lt;a href="#cb7-27"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;FetchUser&lt;/span&gt; (&lt;span class="dt"&gt;Result&lt;/span&gt; &lt;span class="dt"&gt;Http&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Error&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;User&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb7-28"&gt;&lt;a href="#cb7-28"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-29"&gt;&lt;a href="#cb7-29"&gt;&lt;/a&gt;&lt;span class="fu"&gt;init&lt;/span&gt; : () &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Url&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Nav&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Key&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; ( &lt;span class="dt"&gt;Model&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Cmd&lt;/span&gt; &lt;span class="dt"&gt;Msg&lt;/span&gt; )&lt;/span&gt;
&lt;span id="cb7-30"&gt;&lt;a href="#cb7-30"&gt;&lt;/a&gt;&lt;span class="fu"&gt;init&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="fu"&gt;key&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; ( &lt;span class="dt"&gt;Model&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="fu"&gt;key&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Firebase&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;getSignInResult&lt;/span&gt; () )&lt;/span&gt;
&lt;span id="cb7-31"&gt;&lt;a href="#cb7-31"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-32"&gt;&lt;a href="#cb7-32"&gt;&lt;/a&gt;&lt;span class="fu"&gt;update&lt;/span&gt; : &lt;span class="dt"&gt;Msg&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Model&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; ( &lt;span class="dt"&gt;Model&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Cmd&lt;/span&gt; &lt;span class="dt"&gt;Msg&lt;/span&gt; )&lt;/span&gt;
&lt;span id="cb7-33"&gt;&lt;a href="#cb7-33"&gt;&lt;/a&gt;&lt;span class="fu"&gt;update&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-34"&gt;&lt;a href="#cb7-34"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-35"&gt;&lt;a href="#cb7-35"&gt;&lt;/a&gt;        &lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- URL 系は割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-36"&gt;&lt;a href="#cb7-36"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;SignIn&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-37"&gt;&lt;a href="#cb7-37"&gt;&lt;/a&gt;            ( &lt;span class="fu"&gt;model&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Firebase&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;signIn&lt;/span&gt; () )&lt;/span&gt;
&lt;span id="cb7-38"&gt;&lt;a href="#cb7-38"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;SignedIn&lt;/span&gt; (&lt;span class="dt"&gt;Ok&lt;/span&gt; &lt;span class="fu"&gt;token&lt;/span&gt;) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-39"&gt;&lt;a href="#cb7-39"&gt;&lt;/a&gt;            ( { &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;token&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;token&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;error&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt; }&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;getUserInfo&lt;/span&gt; &lt;span class="dt"&gt;FetchUser&lt;/span&gt; &lt;span class="fu"&gt;token&lt;/span&gt; )&lt;/span&gt;
&lt;span id="cb7-40"&gt;&lt;a href="#cb7-40"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;SignedIn&lt;/span&gt; (&lt;span class="dt"&gt;Err&lt;/span&gt; &lt;span class="fu"&gt;err&lt;/span&gt;) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-41"&gt;&lt;a href="#cb7-41"&gt;&lt;/a&gt;            ( { &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;error&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; (&lt;span class="dt"&gt;Json&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;errorToString&lt;/span&gt; &lt;span class="fu"&gt;err&lt;/span&gt;) }&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Cmd&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;none&lt;/span&gt; )&lt;/span&gt;
&lt;span id="cb7-42"&gt;&lt;a href="#cb7-42"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;FetchUser&lt;/span&gt; (&lt;span class="dt"&gt;Ok&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt;) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-43"&gt;&lt;a href="#cb7-43"&gt;&lt;/a&gt;            ( { &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;error&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt; }&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Cmd&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;none&lt;/span&gt; )&lt;/span&gt;
&lt;span id="cb7-44"&gt;&lt;a href="#cb7-44"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;FetchUser&lt;/span&gt; (&lt;span class="dt"&gt;Err&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt;) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-45"&gt;&lt;a href="#cb7-45"&gt;&lt;/a&gt;            ( { &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;error&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;fetch github user error&amp;quot;&lt;/span&gt; }&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Cmd&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;none&lt;/span&gt; )&lt;/span&gt;
&lt;span id="cb7-46"&gt;&lt;a href="#cb7-46"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-47"&gt;&lt;a href="#cb7-47"&gt;&lt;/a&gt;&lt;span class="fu"&gt;view&lt;/span&gt; : &lt;span class="dt"&gt;Model&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Browser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Document&lt;/span&gt; &lt;span class="dt"&gt;Msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-48"&gt;&lt;a href="#cb7-48"&gt;&lt;/a&gt;&lt;span class="fu"&gt;view&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; { &lt;span class="fu"&gt;title&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Elm GitHub OAuth 2.0 Sample&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;body&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; [ &lt;span class="fu"&gt;viewBody&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt; ] }&lt;/span&gt;
&lt;span id="cb7-49"&gt;&lt;a href="#cb7-49"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-50"&gt;&lt;a href="#cb7-50"&gt;&lt;/a&gt;&lt;span class="fu"&gt;viewBody&lt;/span&gt; : &lt;span class="dt"&gt;Model&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Html&lt;/span&gt; &lt;span class="dt"&gt;Msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-51"&gt;&lt;a href="#cb7-51"&gt;&lt;/a&gt;&lt;span class="fu"&gt;viewBody&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-52"&gt;&lt;a href="#cb7-52"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Html&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;div&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;position-relative text-center&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb7-53"&gt;&lt;a href="#cb7-53"&gt;&lt;/a&gt;        [ &lt;span class="cf"&gt;case&lt;/span&gt; ( &lt;span class="fu"&gt;model&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;error&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;user&lt;/span&gt; ) &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-54"&gt;&lt;a href="#cb7-54"&gt;&lt;/a&gt;            ( &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;err&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; ) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-55"&gt;&lt;a href="#cb7-55"&gt;&lt;/a&gt;                &lt;span class="fu"&gt;text&lt;/span&gt; &lt;span class="fu"&gt;err&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-56"&gt;&lt;a href="#cb7-56"&gt;&lt;/a&gt;            ( &lt;span class="fu"&gt;_&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt; ) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-57"&gt;&lt;a href="#cb7-57"&gt;&lt;/a&gt;                &lt;span class="fu"&gt;viewUser&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-58"&gt;&lt;a href="#cb7-58"&gt;&lt;/a&gt;            &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-59"&gt;&lt;a href="#cb7-59"&gt;&lt;/a&gt;                &lt;span class="fu"&gt;signinButton&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-60"&gt;&lt;a href="#cb7-60"&gt;&lt;/a&gt;        ]&lt;/span&gt;
&lt;span id="cb7-61"&gt;&lt;a href="#cb7-61"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-62"&gt;&lt;a href="#cb7-62"&gt;&lt;/a&gt;&lt;span class="fu"&gt;signinButton&lt;/span&gt; : &lt;span class="dt"&gt;Model&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Html&lt;/span&gt; &lt;span class="dt"&gt;Msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-63"&gt;&lt;a href="#cb7-63"&gt;&lt;/a&gt;&lt;span class="fu"&gt;signinButton&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-64"&gt;&lt;a href="#cb7-64"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;div&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;f3 mt-3&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb7-65"&gt;&lt;a href="#cb7-65"&gt;&lt;/a&gt;        [ &lt;span class="fu"&gt;button&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-66"&gt;&lt;a href="#cb7-66"&gt;&lt;/a&gt;            [ &lt;span class="dt"&gt;Event&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;onClick&lt;/span&gt; &lt;span class="dt"&gt;SignIn&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-67"&gt;&lt;a href="#cb7-67"&gt;&lt;/a&gt;            &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- 割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-68"&gt;&lt;a href="#cb7-68"&gt;&lt;/a&gt;            ]&lt;/span&gt;
&lt;span id="cb7-69"&gt;&lt;a href="#cb7-69"&gt;&lt;/a&gt;            [ &lt;span class="fu"&gt;text&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Sign in with GitHub&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb7-70"&gt;&lt;a href="#cb7-70"&gt;&lt;/a&gt;        ]&lt;/span&gt;
&lt;span id="cb7-71"&gt;&lt;a href="#cb7-71"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-72"&gt;&lt;a href="#cb7-72"&gt;&lt;/a&gt;&lt;span class="fu"&gt;viewUser&lt;/span&gt; : &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Html&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-73"&gt;&lt;a href="#cb7-73"&gt;&lt;/a&gt;&lt;span class="fu"&gt;viewUser&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;text&lt;/span&gt; (&lt;span class="st"&gt;&amp;quot;Hi &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;++&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;login&lt;/span&gt; &lt;span class="op"&gt;++&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;!&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;コレを&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ elm make --output=docs/static/main.js src/Main.elm --optimize&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;とビルドして &lt;code&gt;elm reactor&lt;/code&gt; で &lt;code&gt;docs/index.html&lt;/code&gt; にアクセスすると、サインインボタンがあってサインインすると &lt;code&gt;Hi matsubara0507!&lt;/code&gt; って感じのメッセージが出るだけの SPA ができた．&lt;/p&gt;
&lt;h3 id="リポジトリを取得"&gt;リポジトリを取得&lt;/h3&gt;
&lt;p&gt;こっからは完全におまけ． リポジトリのスターをなんかステータスっぽく表示するようにしたい．&lt;/p&gt;
&lt;p&gt;リポジトリ一覧は GitHub の個別ユーザーページをモバイル版でみたときの感じにすることにした：&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/elm-github-oauth2-sample/mobile.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;必要なリポジトリの情報は名前とリンクと総スター数． GitHub API v3 は無駄な情報が多いので，GraphQL を使って一気に取得してみる． GraphQL のクエリの動作確認は&lt;a href="https://developer.github.com/v4/explorer/"&gt;ココ&lt;/a&gt;で行える：&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/elm-github-oauth2-sample/graphql.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;最終的に出来上がったクエリはこんな感じ：&lt;/p&gt;
&lt;pre class="graphql"&gt;&lt;code&gt;query {
  viewer {
    login
    name
    repositories(first: 100, orderBy: {field: STARGAZERS, direction: DESC}, ownerAffiliations: [OWNER], isFork: false) {
      nodes {
        name
        url
        stargazers { totalCount }
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;クエリの &lt;code&gt;viewer {..}&lt;/code&gt; は渡したトークンのユーザー情報を指す． &lt;code&gt;viewer&lt;/code&gt; 内で &lt;code&gt;login&lt;/code&gt; や &lt;code&gt;name&lt;/code&gt; を指定することで，さっきまで v3 で取得していたユーザー情報も取得できる． &lt;code&gt;repositories&lt;/code&gt; で一気に所得できるリポジトリ数は100件が上限（&lt;code&gt;first:300&lt;/code&gt; は怒られる）． &lt;code&gt;orderBy:{..}&lt;/code&gt; でスターの多い順に並び替えて，&lt;code&gt;ownerAffiliations:[OWNER]&lt;/code&gt; と &lt;code&gt;isFork:false&lt;/code&gt; を指定することで自身のリポジトリだけを返してる． リポジトリのスター数は &lt;code&gt;stargazers { totalCount }&lt;/code&gt; で取得できる．&lt;/p&gt;
&lt;h1 id="section"&gt;&lt;/h1&gt;
&lt;p&gt;あとはクエリを叩くだけ． Elm の GraphQL パッケージに良さげのものがなかったのでそのまま &lt;code&gt;elm/http&lt;/code&gt; を使うことにした：&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;GitHub&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="op"&gt;..&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="#cb10-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="#cb10-4"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;login&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="#cb10-5"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;name&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="#cb10-6"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;repos&lt;/span&gt; : &lt;span class="dt"&gt;List&lt;/span&gt; &lt;span class="dt"&gt;Repository&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="#cb10-7"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb10-8"&gt;&lt;a href="#cb10-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-9"&gt;&lt;a href="#cb10-9"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;Repository&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-10"&gt;&lt;a href="#cb10-10"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;name&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-11"&gt;&lt;a href="#cb10-11"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;url&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-12"&gt;&lt;a href="#cb10-12"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;star&lt;/span&gt; : &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-13"&gt;&lt;a href="#cb10-13"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb10-14"&gt;&lt;a href="#cb10-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-15"&gt;&lt;a href="#cb10-15"&gt;&lt;/a&gt;&lt;span class="fu"&gt;userDecoder&lt;/span&gt; : &lt;span class="dt"&gt;Decoder&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-16"&gt;&lt;a href="#cb10-16"&gt;&lt;/a&gt;&lt;span class="fu"&gt;userDecoder&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-17"&gt;&lt;a href="#cb10-17"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map3&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-18"&gt;&lt;a href="#cb10-18"&gt;&lt;/a&gt;        (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;field&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;login&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;string&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-19"&gt;&lt;a href="#cb10-19"&gt;&lt;/a&gt;        (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;field&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;name&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;string&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-20"&gt;&lt;a href="#cb10-20"&gt;&lt;/a&gt;        (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;at&lt;/span&gt; [ &lt;span class="st"&gt;&amp;quot;repositories&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;nodes&amp;quot;&lt;/span&gt; ] (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;list&lt;/span&gt; &lt;span class="fu"&gt;repoDecoder&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb10-21"&gt;&lt;a href="#cb10-21"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-22"&gt;&lt;a href="#cb10-22"&gt;&lt;/a&gt;&lt;span class="fu"&gt;repoDecoder&lt;/span&gt; : &lt;span class="dt"&gt;Decoder&lt;/span&gt; &lt;span class="dt"&gt;Repository&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-23"&gt;&lt;a href="#cb10-23"&gt;&lt;/a&gt;&lt;span class="fu"&gt;repoDecoder&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-24"&gt;&lt;a href="#cb10-24"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map3&lt;/span&gt; &lt;span class="dt"&gt;Repository&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-25"&gt;&lt;a href="#cb10-25"&gt;&lt;/a&gt;        (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;field&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;name&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;string&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-26"&gt;&lt;a href="#cb10-26"&gt;&lt;/a&gt;        (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;field&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;url&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;string&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-27"&gt;&lt;a href="#cb10-27"&gt;&lt;/a&gt;        (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;at&lt;/span&gt; [ &lt;span class="st"&gt;&amp;quot;stargazers&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;totalCount&amp;quot;&lt;/span&gt; ] &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;int&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-28"&gt;&lt;a href="#cb10-28"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-29"&gt;&lt;a href="#cb10-29"&gt;&lt;/a&gt;&lt;span class="fu"&gt;getUserInfo&lt;/span&gt; : (&lt;span class="dt"&gt;Result&lt;/span&gt; &lt;span class="dt"&gt;Http&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Error&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Token&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Cmd&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-30"&gt;&lt;a href="#cb10-30"&gt;&lt;/a&gt;&lt;span class="fu"&gt;getUserInfo&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt; (&lt;span class="dt"&gt;Token&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt;) &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-31"&gt;&lt;a href="#cb10-31"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-32"&gt;&lt;a href="#cb10-32"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;query&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- さっきのクエリをヒアドキュメントとかで&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-33"&gt;&lt;a href="#cb10-33"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;decoder&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; &lt;span class="fu"&gt;identity&lt;/span&gt; (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;at&lt;/span&gt; [ &lt;span class="st"&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;viewer&amp;quot;&lt;/span&gt; ] &lt;span class="fu"&gt;userDecoder&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-34"&gt;&lt;a href="#cb10-34"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-35"&gt;&lt;a href="#cb10-35"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Http&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;request&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-36"&gt;&lt;a href="#cb10-36"&gt;&lt;/a&gt;        { &lt;span class="fu"&gt;method&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-37"&gt;&lt;a href="#cb10-37"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;headers&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; [ &lt;span class="dt"&gt;Http&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;header&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Authorization&amp;quot;&lt;/span&gt; (&lt;span class="st"&gt;&amp;quot;token &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;++&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt;) ]&lt;/span&gt;
&lt;span id="cb10-38"&gt;&lt;a href="#cb10-38"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;url&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;https://api.github.com/graphql&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-39"&gt;&lt;a href="#cb10-39"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;body&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Http&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;jsonBody&lt;/span&gt; (&lt;span class="dt"&gt;E&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;object&lt;/span&gt; [ ( &lt;span class="st"&gt;&amp;quot;query&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;E&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;string&lt;/span&gt; &lt;span class="fu"&gt;query&lt;/span&gt; ) ])&lt;/span&gt;
&lt;span id="cb10-40"&gt;&lt;a href="#cb10-40"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;expect&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Http&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;expectJson&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt; &lt;span class="fu"&gt;decoder&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-41"&gt;&lt;a href="#cb10-41"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;timeout&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-42"&gt;&lt;a href="#cb10-42"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;tracker&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-43"&gt;&lt;a href="#cb10-43"&gt;&lt;/a&gt;        }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;インターフェースは全く変えてないので &lt;code&gt;Main&lt;/code&gt; でいじるのは &lt;code&gt;view&lt;/code&gt; だけ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Main&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="fu"&gt;main&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-3"&gt;&lt;a href="#cb11-3"&gt;&lt;/a&gt;&lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-4"&gt;&lt;a href="#cb11-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-5"&gt;&lt;a href="#cb11-5"&gt;&lt;/a&gt;&lt;span class="fu"&gt;viewUser&lt;/span&gt; : &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Html&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-6"&gt;&lt;a href="#cb11-6"&gt;&lt;/a&gt;&lt;span class="fu"&gt;viewUser&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-7"&gt;&lt;a href="#cb11-7"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-8"&gt;&lt;a href="#cb11-8"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;total&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;fromInt&lt;/span&gt; (&lt;span class="dt"&gt;List&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;sum&lt;/span&gt; (&lt;span class="dt"&gt;List&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; &lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;star&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;repos&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb11-9"&gt;&lt;a href="#cb11-9"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-10"&gt;&lt;a href="#cb11-10"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;div&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;container-sm my-3&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb11-11"&gt;&lt;a href="#cb11-11"&gt;&lt;/a&gt;        [ &lt;span class="fu"&gt;h3&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;my-2&amp;quot;&lt;/span&gt; ] [ &lt;span class="fu"&gt;text&lt;/span&gt; (&lt;span class="fu"&gt;user&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;login&lt;/span&gt; &lt;span class="op"&gt;++&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&amp;#39;s points: &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;++&lt;/span&gt; &lt;span class="fu"&gt;total&lt;/span&gt;) ]&lt;/span&gt;
&lt;span id="cb11-12"&gt;&lt;a href="#cb11-12"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;viewRepositories&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-13"&gt;&lt;a href="#cb11-13"&gt;&lt;/a&gt;        ]&lt;/span&gt;
&lt;span id="cb11-14"&gt;&lt;a href="#cb11-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-15"&gt;&lt;a href="#cb11-15"&gt;&lt;/a&gt;&lt;span class="fu"&gt;viewRepositories&lt;/span&gt; : &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Html&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-16"&gt;&lt;a href="#cb11-16"&gt;&lt;/a&gt;&lt;span class="fu"&gt;viewRepositories&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-17"&gt;&lt;a href="#cb11-17"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-18"&gt;&lt;a href="#cb11-18"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;viewRepository&lt;/span&gt; &lt;span class="fu"&gt;repo&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-19"&gt;&lt;a href="#cb11-19"&gt;&lt;/a&gt;            &lt;span class="fu"&gt;li&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Box-row mb-3&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb11-20"&gt;&lt;a href="#cb11-20"&gt;&lt;/a&gt;                [ &lt;span class="fu"&gt;div&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;float-left&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb11-21"&gt;&lt;a href="#cb11-21"&gt;&lt;/a&gt;                    [ &lt;span class="dt"&gt;Octicons&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;repo&lt;/span&gt; &lt;span class="dt"&gt;Octicons&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;defaultOptions&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-22"&gt;&lt;a href="#cb11-22"&gt;&lt;/a&gt;                    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;a&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;href&lt;/span&gt; &lt;span class="fu"&gt;repo&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;url&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;ml-1&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb11-23"&gt;&lt;a href="#cb11-23"&gt;&lt;/a&gt;                        [ &lt;span class="fu"&gt;text&lt;/span&gt; (&lt;span class="fu"&gt;user&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;login&lt;/span&gt; &lt;span class="op"&gt;++&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;++&lt;/span&gt; &lt;span class="fu"&gt;repo&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;name&lt;/span&gt;) ]&lt;/span&gt;
&lt;span id="cb11-24"&gt;&lt;a href="#cb11-24"&gt;&lt;/a&gt;                    ]&lt;/span&gt;
&lt;span id="cb11-25"&gt;&lt;a href="#cb11-25"&gt;&lt;/a&gt;                &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;div&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;float-right&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb11-26"&gt;&lt;a href="#cb11-26"&gt;&lt;/a&gt;                    [ &lt;span class="fu"&gt;text&lt;/span&gt; (&lt;span class="dt"&gt;String&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;fromInt&lt;/span&gt; &lt;span class="fu"&gt;repo&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;star&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb11-27"&gt;&lt;a href="#cb11-27"&gt;&lt;/a&gt;                    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Octicons&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;star&lt;/span&gt; &lt;span class="dt"&gt;Octicons&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;defaultOptions&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-28"&gt;&lt;a href="#cb11-28"&gt;&lt;/a&gt;                    ]&lt;/span&gt;
&lt;span id="cb11-29"&gt;&lt;a href="#cb11-29"&gt;&lt;/a&gt;                ]&lt;/span&gt;
&lt;span id="cb11-30"&gt;&lt;a href="#cb11-30"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-31"&gt;&lt;a href="#cb11-31"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;div&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Box&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb11-32"&gt;&lt;a href="#cb11-32"&gt;&lt;/a&gt;        [ &lt;span class="fu"&gt;ul&lt;/span&gt; [] (&lt;span class="dt"&gt;List&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; &lt;span class="fu"&gt;viewRepository&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;repos&lt;/span&gt;) ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="elm-で円グラフ"&gt;Elm で円グラフ&lt;/h3&gt;
&lt;p&gt;なんかこう，リポジトリのプライマリ言語ごとに円グラフにしたら面白いなっていう欲がでてきたのでそうしてみることにした． まずはリポジトリのプライマリ言語を返すようにクエリをいじる：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;query {
  viewer {
    ...
    repositories(...) {
      nodes {
        ...
        primaryLanguage {
          name
          color
        }
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;データ構造も書き足す：&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb13-1"&gt;&lt;a href="#cb13-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;Repository&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="#cb13-2"&gt;&lt;/a&gt;    { &lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- 割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-3"&gt;&lt;a href="#cb13-3"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;language&lt;/span&gt; : &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Language&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-4"&gt;&lt;a href="#cb13-4"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb13-5"&gt;&lt;a href="#cb13-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-6"&gt;&lt;a href="#cb13-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;Language&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-7"&gt;&lt;a href="#cb13-7"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;name&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-8"&gt;&lt;a href="#cb13-8"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;color&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-9"&gt;&lt;a href="#cb13-9"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb13-10"&gt;&lt;a href="#cb13-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-11"&gt;&lt;a href="#cb13-11"&gt;&lt;/a&gt;&lt;span class="fu"&gt;repoDecoder&lt;/span&gt; : &lt;span class="dt"&gt;Decoder&lt;/span&gt; &lt;span class="dt"&gt;Repository&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-12"&gt;&lt;a href="#cb13-12"&gt;&lt;/a&gt;&lt;span class="fu"&gt;repoDecoder&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-13"&gt;&lt;a href="#cb13-13"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map4&lt;/span&gt; &lt;span class="dt"&gt;Repository&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-14"&gt;&lt;a href="#cb13-14"&gt;&lt;/a&gt;        &lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- 割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-15"&gt;&lt;a href="#cb13-15"&gt;&lt;/a&gt;        (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;field&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;primaryLanguage&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;|&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;nullable&lt;/span&gt; &lt;span class="fu"&gt;languageDecoder&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb13-16"&gt;&lt;a href="#cb13-16"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-17"&gt;&lt;a href="#cb13-17"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-18"&gt;&lt;a href="#cb13-18"&gt;&lt;/a&gt;&lt;span class="fu"&gt;languageDecoder&lt;/span&gt; : &lt;span class="dt"&gt;Decoder&lt;/span&gt; &lt;span class="dt"&gt;Language&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-19"&gt;&lt;a href="#cb13-19"&gt;&lt;/a&gt;&lt;span class="fu"&gt;languageDecoder&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-20"&gt;&lt;a href="#cb13-20"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map2&lt;/span&gt; &lt;span class="dt"&gt;Language&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-21"&gt;&lt;a href="#cb13-21"&gt;&lt;/a&gt;        (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;field&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;name&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;string&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb13-22"&gt;&lt;a href="#cb13-22"&gt;&lt;/a&gt;        (&lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;field&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;color&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;string&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;プライマリ言語の情報は &lt;code&gt;null&lt;/code&gt; が返ってくる可能性があるので、&lt;code&gt;Maybe&lt;/code&gt; でラップしている．&lt;/p&gt;
&lt;p&gt;データは揃ったので，あとは円グラフを描くだけ． 円グラフの描写には &lt;a href="https://package.elm-lang.org/packages/gampleman/elm-visualization/2.1.1"&gt;&lt;code&gt;gampleman/elm-visualization&lt;/code&gt;&lt;/a&gt; を使うことにする． example 集にある「&lt;a href="https://elm-visualization.netlify.com/custompiechart"&gt;Custom Pie Chart&lt;/a&gt;」をベースにすることにした． コピペしてよしなに書き換える：&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb14-1"&gt;&lt;a href="#cb14-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Pie&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="fu"&gt;view&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="#cb14-2"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- import は割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="#cb14-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-4"&gt;&lt;a href="#cb14-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;Data&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-5"&gt;&lt;a href="#cb14-5"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;label&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="co"&gt;-- 言語名&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-6"&gt;&lt;a href="#cb14-6"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;data&lt;/span&gt; : &lt;span class="dt"&gt;Float&lt;/span&gt;   &lt;span class="co"&gt;-- 総スター数&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-7"&gt;&lt;a href="#cb14-7"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;color&lt;/span&gt; : &lt;span class="dt"&gt;Color&lt;/span&gt;  &lt;span class="co"&gt;-- GitHub 側で設定されてる言語の色&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-8"&gt;&lt;a href="#cb14-8"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb14-9"&gt;&lt;a href="#cb14-9"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-10"&gt;&lt;a href="#cb14-10"&gt;&lt;/a&gt;&lt;span class="fu"&gt;w&lt;/span&gt; : &lt;span class="dt"&gt;Float&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-11"&gt;&lt;a href="#cb14-11"&gt;&lt;/a&gt;&lt;span class="fu"&gt;w&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;990&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-12"&gt;&lt;a href="#cb14-12"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-13"&gt;&lt;a href="#cb14-13"&gt;&lt;/a&gt;&lt;span class="fu"&gt;h&lt;/span&gt; : &lt;span class="dt"&gt;Float&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-14"&gt;&lt;a href="#cb14-14"&gt;&lt;/a&gt;&lt;span class="fu"&gt;h&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;504&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-15"&gt;&lt;a href="#cb14-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-16"&gt;&lt;a href="#cb14-16"&gt;&lt;/a&gt;&lt;span class="fu"&gt;radius&lt;/span&gt; : &lt;span class="dt"&gt;Float&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-17"&gt;&lt;a href="#cb14-17"&gt;&lt;/a&gt;&lt;span class="fu"&gt;radius&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;min&lt;/span&gt; &lt;span class="fu"&gt;w&lt;/span&gt; &lt;span class="fu"&gt;h&lt;/span&gt; &lt;span class="op"&gt;/&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-18"&gt;&lt;a href="#cb14-18"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-19"&gt;&lt;a href="#cb14-19"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;ChartConfig&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-20"&gt;&lt;a href="#cb14-20"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;outerRadius&lt;/span&gt; : &lt;span class="dt"&gt;Float&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-21"&gt;&lt;a href="#cb14-21"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;innerRadius&lt;/span&gt; : &lt;span class="dt"&gt;Float&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-22"&gt;&lt;a href="#cb14-22"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;padAngle&lt;/span&gt; : &lt;span class="dt"&gt;Float&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-23"&gt;&lt;a href="#cb14-23"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;cornerRadius&lt;/span&gt; : &lt;span class="dt"&gt;Float&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-24"&gt;&lt;a href="#cb14-24"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;labelPosition&lt;/span&gt; : &lt;span class="dt"&gt;Float&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-25"&gt;&lt;a href="#cb14-25"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb14-26"&gt;&lt;a href="#cb14-26"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-27"&gt;&lt;a href="#cb14-27"&gt;&lt;/a&gt;&lt;span class="fu"&gt;drawChart&lt;/span&gt; : &lt;span class="dt"&gt;ChartConfig&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;List&lt;/span&gt; &lt;span class="dt"&gt;Data&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Svg&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-28"&gt;&lt;a href="#cb14-28"&gt;&lt;/a&gt;&lt;span class="fu"&gt;drawChart&lt;/span&gt; &lt;span class="fu"&gt;config&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-29"&gt;&lt;a href="#cb14-29"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-30"&gt;&lt;a href="#cb14-30"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;pieData&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-31"&gt;&lt;a href="#cb14-31"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;List&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; &lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;data&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-32"&gt;&lt;a href="#cb14-32"&gt;&lt;/a&gt;                &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Shape&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;pie&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-33"&gt;&lt;a href="#cb14-33"&gt;&lt;/a&gt;                    { &lt;span class="fu"&gt;defaultPieConfig&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-34"&gt;&lt;a href="#cb14-34"&gt;&lt;/a&gt;                        &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;innerRadius&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;config&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;innerRadius&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-35"&gt;&lt;a href="#cb14-35"&gt;&lt;/a&gt;                        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;outerRadius&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;config&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;outerRadius&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-36"&gt;&lt;a href="#cb14-36"&gt;&lt;/a&gt;                        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;padAngle&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;config&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;padAngle&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-37"&gt;&lt;a href="#cb14-37"&gt;&lt;/a&gt;                        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;cornerRadius&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;config&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;cornerRadius&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-38"&gt;&lt;a href="#cb14-38"&gt;&lt;/a&gt;                        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;sortingFn&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; \&lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;EQ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-39"&gt;&lt;a href="#cb14-39"&gt;&lt;/a&gt;                    }&lt;/span&gt;
&lt;span id="cb14-40"&gt;&lt;a href="#cb14-40"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-41"&gt;&lt;a href="#cb14-41"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;makeSlice&lt;/span&gt; &lt;span class="fu"&gt;pieDatum&lt;/span&gt; &lt;span class="fu"&gt;datum&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-42"&gt;&lt;a href="#cb14-42"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Path&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;element&lt;/span&gt; (&lt;span class="dt"&gt;Shape&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;arc&lt;/span&gt; &lt;span class="fu"&gt;pieDatum&lt;/span&gt;) [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;fill&lt;/span&gt; (&lt;span class="dt"&gt;Paint&lt;/span&gt; &lt;span class="fu"&gt;datum&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;color&lt;/span&gt;) ]&lt;/span&gt;
&lt;span id="cb14-43"&gt;&lt;a href="#cb14-43"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-44"&gt;&lt;a href="#cb14-44"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;makeLabel&lt;/span&gt; &lt;span class="fu"&gt;pieDatum&lt;/span&gt; &lt;span class="fu"&gt;datum&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-45"&gt;&lt;a href="#cb14-45"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-46"&gt;&lt;a href="#cb14-46"&gt;&lt;/a&gt;                ( &lt;span class="fu"&gt;x&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;y&lt;/span&gt; ) &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-47"&gt;&lt;a href="#cb14-47"&gt;&lt;/a&gt;                    &lt;span class="dt"&gt;Shape&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;centroid&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-48"&gt;&lt;a href="#cb14-48"&gt;&lt;/a&gt;                        { &lt;span class="fu"&gt;pieDatum&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-49"&gt;&lt;a href="#cb14-49"&gt;&lt;/a&gt;                            &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;innerRadius&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;config&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;labelPosition&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-50"&gt;&lt;a href="#cb14-50"&gt;&lt;/a&gt;                            &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;outerRadius&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;config&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;labelPosition&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-51"&gt;&lt;a href="#cb14-51"&gt;&lt;/a&gt;                        }&lt;/span&gt;
&lt;span id="cb14-52"&gt;&lt;a href="#cb14-52"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-53"&gt;&lt;a href="#cb14-53"&gt;&lt;/a&gt;            &lt;span class="fu"&gt;text_&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-54"&gt;&lt;a href="#cb14-54"&gt;&lt;/a&gt;                [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;transform&lt;/span&gt; [ &lt;span class="dt"&gt;Translate&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt; &lt;span class="fu"&gt;y&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb14-55"&gt;&lt;a href="#cb14-55"&gt;&lt;/a&gt;                &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;dy&lt;/span&gt; (&lt;span class="fu"&gt;em&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dv"&gt;35&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb14-56"&gt;&lt;a href="#cb14-56"&gt;&lt;/a&gt;                &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;textAnchor&lt;/span&gt; &lt;span class="dt"&gt;AnchorMiddle&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-57"&gt;&lt;a href="#cb14-57"&gt;&lt;/a&gt;                ]&lt;/span&gt;
&lt;span id="cb14-58"&gt;&lt;a href="#cb14-58"&gt;&lt;/a&gt;                [ &lt;span class="fu"&gt;text&lt;/span&gt; &lt;span class="fu"&gt;datum&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;label&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb14-59"&gt;&lt;a href="#cb14-59"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-60"&gt;&lt;a href="#cb14-60"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;svg&lt;/span&gt; [ &lt;span class="fu"&gt;width&lt;/span&gt; (&lt;span class="fu"&gt;radius&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;)&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;height&lt;/span&gt; (&lt;span class="fu"&gt;radius&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;) ]&lt;/span&gt;
&lt;span id="cb14-61"&gt;&lt;a href="#cb14-61"&gt;&lt;/a&gt;        [ &lt;span class="fu"&gt;g&lt;/span&gt; [ &lt;span class="dt"&gt;Attr&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;transform&lt;/span&gt; [ &lt;span class="dt"&gt;Translate&lt;/span&gt; &lt;span class="fu"&gt;radius&lt;/span&gt; &lt;span class="fu"&gt;radius&lt;/span&gt; ] ]&lt;/span&gt;
&lt;span id="cb14-62"&gt;&lt;a href="#cb14-62"&gt;&lt;/a&gt;            [ &lt;span class="fu"&gt;g&lt;/span&gt; [] &lt;span class="op"&gt;&amp;lt;|&lt;/span&gt; &lt;span class="dt"&gt;List&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map2&lt;/span&gt; &lt;span class="fu"&gt;makeSlice&lt;/span&gt; &lt;span class="fu"&gt;pieData&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-63"&gt;&lt;a href="#cb14-63"&gt;&lt;/a&gt;            &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;g&lt;/span&gt; [] &lt;span class="op"&gt;&amp;lt;|&lt;/span&gt; &lt;span class="dt"&gt;List&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map2&lt;/span&gt; &lt;span class="fu"&gt;makeLabel&lt;/span&gt; &lt;span class="fu"&gt;pieData&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-64"&gt;&lt;a href="#cb14-64"&gt;&lt;/a&gt;            ]&lt;/span&gt;
&lt;span id="cb14-65"&gt;&lt;a href="#cb14-65"&gt;&lt;/a&gt;        ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;主に書き換えたのは色の部分． example では &lt;code&gt;colors&lt;/code&gt; 的な色リストを利用してたが，リポジトリのプログラミング言語には GitHub 側で色が設定してあるので，それをモデルに持たせて引用することにした． あとは &lt;code&gt;Repository&lt;/code&gt; 型から &lt;code&gt;Data&lt;/code&gt; 型を組み立てる部分を書くだけ：&lt;/p&gt;
&lt;div class="sourceCode" id="cb15"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb15-1"&gt;&lt;a href="#cb15-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;Pie&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="fu"&gt;view&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb15-2"&gt;&lt;a href="#cb15-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb15-3"&gt;&lt;a href="#cb15-3"&gt;&lt;/a&gt;&lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- 割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-4"&gt;&lt;a href="#cb15-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb15-5"&gt;&lt;a href="#cb15-5"&gt;&lt;/a&gt;&lt;span class="fu"&gt;fromRepo&lt;/span&gt; : &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Repository&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Data&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-6"&gt;&lt;a href="#cb15-6"&gt;&lt;/a&gt;&lt;span class="fu"&gt;fromRepo&lt;/span&gt; &lt;span class="fu"&gt;repo&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-7"&gt;&lt;a href="#cb15-7"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;repo&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;language&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-8"&gt;&lt;a href="#cb15-8"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-9"&gt;&lt;a href="#cb15-9"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Data&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;none&amp;quot;&lt;/span&gt; (&lt;span class="fu"&gt;toFloat&lt;/span&gt; &lt;span class="fu"&gt;repo&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;star&lt;/span&gt;) &lt;span class="dt"&gt;Color&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;black&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-10"&gt;&lt;a href="#cb15-10"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;lang&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-11"&gt;&lt;a href="#cb15-11"&gt;&lt;/a&gt;            &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;hexToColor&lt;/span&gt; &lt;span class="fu"&gt;lang&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;color&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-12"&gt;&lt;a href="#cb15-12"&gt;&lt;/a&gt;                &lt;span class="dt"&gt;Ok&lt;/span&gt; &lt;span class="fu"&gt;c&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-13"&gt;&lt;a href="#cb15-13"&gt;&lt;/a&gt;                    &lt;span class="dt"&gt;Data&lt;/span&gt; &lt;span class="fu"&gt;lang&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;name&lt;/span&gt; (&lt;span class="fu"&gt;toFloat&lt;/span&gt; &lt;span class="fu"&gt;repo&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;star&lt;/span&gt;) &lt;span class="fu"&gt;c&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-14"&gt;&lt;a href="#cb15-14"&gt;&lt;/a&gt;                &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-15"&gt;&lt;a href="#cb15-15"&gt;&lt;/a&gt;                    &lt;span class="dt"&gt;Data&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;none&amp;quot;&lt;/span&gt; (&lt;span class="fu"&gt;toFloat&lt;/span&gt; &lt;span class="fu"&gt;repo&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;star&lt;/span&gt;) &lt;span class="dt"&gt;Color&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;black&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-16"&gt;&lt;a href="#cb15-16"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb15-17"&gt;&lt;a href="#cb15-17"&gt;&lt;/a&gt;&lt;span class="fu"&gt;view&lt;/span&gt; : &lt;span class="dt"&gt;GitHub&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Html&lt;/span&gt; &lt;span class="fu"&gt;msg&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-18"&gt;&lt;a href="#cb15-18"&gt;&lt;/a&gt;&lt;span class="fu"&gt;view&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-19"&gt;&lt;a href="#cb15-19"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-20"&gt;&lt;a href="#cb15-20"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;config&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- 割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-21"&gt;&lt;a href="#cb15-21"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb15-22"&gt;&lt;a href="#cb15-22"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;updateBy&lt;/span&gt; &lt;span class="fu"&gt;d&lt;/span&gt; &lt;span class="fu"&gt;value&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-23"&gt;&lt;a href="#cb15-23"&gt;&lt;/a&gt;            &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;value&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-24"&gt;&lt;a href="#cb15-24"&gt;&lt;/a&gt;                &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-25"&gt;&lt;a href="#cb15-25"&gt;&lt;/a&gt;                    &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;d&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-26"&gt;&lt;a href="#cb15-26"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb15-27"&gt;&lt;a href="#cb15-27"&gt;&lt;/a&gt;                &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;v&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-28"&gt;&lt;a href="#cb15-28"&gt;&lt;/a&gt;                    &lt;span class="dt"&gt;Just&lt;/span&gt; { &lt;span class="fu"&gt;v&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;data&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;v&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;data&lt;/span&gt; &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="fu"&gt;d&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;data&lt;/span&gt; }&lt;/span&gt;
&lt;span id="cb15-29"&gt;&lt;a href="#cb15-29"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb15-30"&gt;&lt;a href="#cb15-30"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;model&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-31"&gt;&lt;a href="#cb15-31"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;List&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; &lt;span class="fu"&gt;fromRepo&lt;/span&gt; &lt;span class="fu"&gt;user&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;repos&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-32"&gt;&lt;a href="#cb15-32"&gt;&lt;/a&gt;                &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;List&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;foldl&lt;/span&gt; (\&lt;span class="fu"&gt;d&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Dict&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;update&lt;/span&gt; &lt;span class="fu"&gt;d&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;label&lt;/span&gt; (&lt;span class="fu"&gt;updateBy&lt;/span&gt; &lt;span class="fu"&gt;d&lt;/span&gt;)) &lt;span class="dt"&gt;Dict&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;empty&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-33"&gt;&lt;a href="#cb15-33"&gt;&lt;/a&gt;                &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Dict&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;filter&lt;/span&gt; (\&lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="fu"&gt;v&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;v&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;data&lt;/span&gt; &lt;span class="op"&gt;/=&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb15-34"&gt;&lt;a href="#cb15-34"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-35"&gt;&lt;a href="#cb15-35"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;div&lt;/span&gt; [ &lt;span class="fu"&gt;class&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;position-relative&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb15-36"&gt;&lt;a href="#cb15-36"&gt;&lt;/a&gt;        [ &lt;span class="fu"&gt;drawChart&lt;/span&gt; &lt;span class="fu"&gt;config&lt;/span&gt; (&lt;span class="dt"&gt;Dict&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;values&lt;/span&gt; &lt;span class="fu"&gt;model&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb15-37"&gt;&lt;a href="#cb15-37"&gt;&lt;/a&gt;        ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;色々考えた結果，いったん各 &lt;code&gt;Repository&lt;/code&gt; を &lt;code&gt;Data&lt;/code&gt; に変換して，そのあと言語名をキーにした &lt;code&gt;Dict&lt;/code&gt; へと畳み込んでいる（&lt;code&gt;.data&lt;/code&gt; の部分だけ足し合わせてる）． あとは &lt;code&gt;Pie.view user&lt;/code&gt; を &lt;code&gt;Main.view&lt;/code&gt; で呼び出すだけ．&lt;/p&gt;
&lt;p&gt;あ、ちなみに真ん中にアバター画像出したしてるのは割愛（ただ単にアバター画像を GraphQL で取ってきて，&lt;code&gt;Pie.view&lt;/code&gt; で重ねてるだけ）．&lt;/p&gt;
&lt;h2 id="おしまい"&gt;おしまい&lt;/h2&gt;
&lt;p&gt;Firebase 便利ですね．&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/02/08/141129</id><title type="text">標準入力の一行の上限は4,096バイト</title><updated>2020-02-08T14:12:33+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/02/08/141129"/><summary type="html">標準入力の一行に大量の文字を食わせると、4,096バイトしか有効にならない。 $ perl -e 'print "x" x 5000, "\n" for 1 .. 2' | clip.exe $ perl -e 'print length &lt;&gt;, "\n" for 1 .. 3' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/02/05/231811</id><title type="text">rustでdiscordのbotを作ってみたくて下調べ(3)</title><updated>2020-02-05T23:19:13+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/02/05/231811"/><summary type="html">前回からだいぶ時間が空いたが、下調べの続き。 discord-rs というのを最初に見つけて古いと嘆いていたのだが、現在使われているクレートは serenity の方だったようだ。これを検索で見つけるのは至難の業。 discord で検索すると、他の関係ないクレートがガンガン引っかかってしまうので（恐らく、いろいろなクレートでサポート用の discord チャネルがあるため）。 serenity は非常に重厚なクレートで、 discord.py に設計思想が近い。 #[command] マクロを使うことで、簡単に bot コマンドを作ることができる。これは framework feature …</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/11/20/GHC_%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89_%E6%A6%82%E8%A6%B3_%E3%81%A8_PowerShell</id><title type="text">GHC 環境構築 概観 と PowerShell</title><updated>2020-01-27T09:06:24+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/11/20/GHC_%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89_%E6%A6%82%E8%A6%B3_%E3%81%A8_PowerShell"/><summary type="html">Haskell の開発環境を構築する方法は何通りかあり、新しいツールが出ると「今はこれだ」とほめるブログも公開されますがそれが初学者を混乱させることがよくあります。 本記事ではビルドツールのインストールにしぼり、開発支援、例えば ghc-mod・haskell-ide-engine・hhp には言及しません。 いくつか典型的な構築方法を確認した後、新たに私が作成したツールを紹介しより初学者を混乱に落とし入れます。 重鎮 Haskell Platform www.haskell.org Haskell 解説書史1の第1波から第3波までのデファクトスタンダードであった重鎮 Haskell Plat…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2018/04/10/100000</id><title type="text">バイナリエディタを作りました！</title><updated>2020-01-25T19:17:58+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2018/04/10/100000"/><summary type="html">バイナリエディタを作りました。 インストールはHomebrew brew install itchyny/tap/bed または以下のコマンドでできます。 go get github.com/itchyny/bed/cmd/bed なぜ作ったのか 私は昔からファイルフォーマットに興味があり、画像ファイルやPDFファイルのフォーマットを調べるのが好きでした。 最近も圧縮ファイルのフォーマットを趣味で調べたりしています。 コンパイラ技術にも興味があり、ゆくゆくは実行ファイルを生成したりしたいなという思いもあります。 バイナリファイルをエディットするにはバイナリエディタが必要となるわけですが、自分の…</summary></entry><entry><id>https://kurokawh.blogspot.com/2018/01/cygwin-cygwin.html</id><title type="text">[cygwin] cygwinセットアップ・環境構築手順メモ</title><updated>2020-01-20T11:46:31.459+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2018/01/cygwin-cygwin.html"/><summary type="text">

主に自分向けの防備録です。windows10上で確認。インストーラーはここからDLする。





&lt;&lt;設定&gt;&gt;

ssh-agentの重複起動を防ぐ


ユーザーのアカウント名、ホームディレクトリの変更



/etc/passwdを編集する（最新バージョンでは自動生成されない？）
Cygwinを移動したら/etc/passwdの再生成を
巨大ドメインに参加している PC での /etc/passwd, /etc/group ファイルのつくりかた 

ssh-agentのために秘密鍵セットアップ



~/.ssh/


※group/otherの権限を削除する必要がある

% chmod 700 ~/.ssh 


less, lv, manコマンド終了時に画面をクリアしない

[linux][cygwin] less, manの終了直前の画面をクリアしないで端末上に残す方法 
</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2020/01/10/100000</id><title type="text">ファイルをエディターで一括リネームするツールをGo言語で作った！ ― 機能を増やさない信念と、OSSとの付き合い方</title><updated>2020-01-10T10:00:09+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2020/01/10/100000"/><summary type="html">ファイルを一括でリネームしたいことはありませんか。私はあります。ということで作りました。 インストールはHomebrew brew install itchyny/tap/mmv または以下のコマンドでできます。 go get github.com/itchyny/mmv/cmd/mmv スクリーンショットではvimが起動していますが、 $EDITOR が設定されていればそれを使って編集することができます。 エディターでファイル名を編集して一括でリネームするというのは、新しい発想ではありません。 実際、多くのソフトウェア (特にファイラー) がこの機能を実装しています。 massren vim…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2020-01-08-calc-ssh-pubkey-fingerprint-with-haskell.html</id><title type="text">Haskell で SSH Public Key の FingerPrint を計算する</title><updated>2020-01-08T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2020-01-08-calc-ssh-pubkey-fingerprint-with-haskell.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;GitHub に登録している Public Key から &lt;code&gt;~/.ssh/authorized_key&lt;/code&gt; を生成する簡易的な CLI ツールを作ろうと考えた． そして，Public Key をフィルタリングするために &lt;code&gt;https://github.com/settings/keys&lt;/code&gt; で参照できる FingerPrint を使おうと考えたが，その場合は GitHub API で取得した Public Key から FingerPrint をプログラム側で計算しないといけない．&lt;/p&gt;
&lt;p&gt;もちろん，&lt;code&gt;ssh-keygen -l -E md5 -f ssh_host_ecdsa_key.pub&lt;/code&gt; なんかで生成できるのだが可能なら素の Haskell プログラムでやりたいなと考えた． ということで，本記事はタイトルの通り Haskell で SSH Public Key の FingerPrint を計算することになったので，そのために色々調べたメモ書き．&lt;/p&gt;
&lt;h2 id="fingerprint"&gt;FingerPrint&lt;/h2&gt;
&lt;p&gt;そもそもどういうアルゴリズムで出しているのか． ちょうど良い記事があった，ありがたい:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://qiita.com/hotpepsi/items/128f3a660cee8b5467c6"&gt;RSA公開鍵のファイル形式とfingerprint - Qiita&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要するに Base64 デコードして MD5 ハッシュをかければ良いようだ（本来は SHA256 の方が良いっぽいけど）． 上記記事では Base64 デコードしてできた &lt;a href="https://www.ietf.org/rfc/rfc4253.txt"&gt;RFC4253&lt;/a&gt; の中身まで説明してくれており，最後の Ruby プログラムではバイナリをちゃんと読んだ上で FingerPrint を計算している．&lt;/p&gt;
&lt;p&gt;単純に RSA 形式の Public Key の FingerPrint を計算するだけならそこまでしなくて良さそうだ．&lt;/p&gt;
&lt;h2 id="haskell-で計算する"&gt;Haskell で計算する&lt;/h2&gt;
&lt;p&gt;上述の通りやることは2つ&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;Base64 デコード&lt;/li&gt;
&lt;li&gt;MD5 ハッシュ化&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;あとその前に header と body を切り分ける．&lt;/p&gt;
&lt;p&gt;ちなみに，最終的なコードは &lt;a href="https://github.com/haskell-jp/playground/pull/1"&gt;haskell-jp/playground&lt;/a&gt; においた．&lt;/p&gt;
&lt;h3 id="header-と-body-を切り分ける"&gt;header と body を切り分ける&lt;/h3&gt;
&lt;p&gt;RSA の Public Key は &lt;code&gt;ssh-rsa AAAAXXX...&lt;/code&gt; となっている（&lt;code&gt;X&lt;/code&gt; 以降は適当）． 欲しいのは空白よりあとだけなので，まずはそこを切り出す（ついでにバリデーションする）． 後々楽なので全部 &lt;code&gt;ByteString&lt;/code&gt; を使うことにする:&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.ByteString&lt;/span&gt; (&lt;span class="dt"&gt;ByteString&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.ByteString&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;B&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4"&gt;&lt;/a&gt;&lt;span class="ot"&gt;pubkeyBody ::&lt;/span&gt; &lt;span class="dt"&gt;ByteString&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;ByteString&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5"&gt;&lt;/a&gt;pubkeyBody content &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;case&lt;/span&gt; B.split &lt;span class="dv"&gt;32&lt;/span&gt; content &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7"&gt;&lt;/a&gt;    [header, body] &lt;span class="op"&gt;|&lt;/span&gt; header &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;ssh-rsa&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;AAAA&amp;quot;&lt;/span&gt; &lt;span class="ot"&gt;`B.isPrefixOf`&lt;/span&gt; body &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Just&lt;/span&gt; body&lt;/span&gt;
&lt;span id="cb1-9"&gt;&lt;a href="#cb1-9"&gt;&lt;/a&gt;    _ &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-10"&gt;&lt;a href="#cb1-10"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Word8&lt;/code&gt; 型の &lt;code&gt;32&lt;/code&gt; は空白．&lt;/p&gt;
&lt;h3 id="base64-デコード"&gt;Base64 デコード&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://hackage.haskell.org/package/memory"&gt;memory&lt;/a&gt; というパッケージを使う． なぜかというと，この後で使うあらゆる暗号アルゴリズムを詰め込んだ &lt;a href="http://hackage.haskell.org/package/cryptonite"&gt;cryptonite&lt;/a&gt; というパッケージがこれに依存していたからだ． cryptonite に習って Base64 デコードするとこんな感じだ（ついでにバリデーションする）:&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- これが memory パッケージのモジュール&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.ByteArray.Encoding&lt;/span&gt; (&lt;span class="dt"&gt;Base&lt;/span&gt; (&lt;span class="dt"&gt;Base64&lt;/span&gt;), convertFromBase)&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4"&gt;&lt;/a&gt;&lt;span class="ot"&gt;decode ::&lt;/span&gt; &lt;span class="dt"&gt;ByteString&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;ByteString&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5"&gt;&lt;/a&gt;decode body &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;case&lt;/span&gt; convertFromBase &lt;span class="dt"&gt;Base64&lt;/span&gt; body &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Right&lt;/span&gt; bin &lt;span class="op"&gt;|&lt;/span&gt; prefix &lt;span class="ot"&gt;`B.isPrefixOf`&lt;/span&gt; bin &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Just&lt;/span&gt; bin&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9"&gt;&lt;/a&gt;    _ &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="#cb2-10"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="#cb2-11"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-12"&gt;&lt;a href="#cb2-12"&gt;&lt;/a&gt;    &lt;span class="co"&gt;-- \x00 \x00 \x00 \x07 ssh-rsa (00000007 というのは ssh-rsa の長さ)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-13"&gt;&lt;a href="#cb2-13"&gt;&lt;/a&gt;    prefix &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\NUL\NUL\NUL\assh-rsa&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="md5-ハッシュ化"&gt;MD5 ハッシュ化&lt;/h3&gt;
&lt;p&gt;上述の通り，cryptonite というのを用いる． ちなみにこれらのパッケージについては &lt;a href="https://fpcomplete.com/cryptographic-hashing-in-haskell"&gt;Cryptographic Hashing in Haskell - FPComplete&lt;/a&gt; で紹介されてる(&lt;a href="https://haskell.e-bigmoon.com/posts/2017/09-18-cryptographic-hashing-haskell.html"&gt;邦訳記事&lt;/a&gt;)． 2017年と少し古い記事だが，このパッケージは今でも精力的にメンテナンスがされており，また個人ではなくチーム(&lt;a href="https://github.com/haskell-crypto"&gt;Haskell Crypto&lt;/a&gt;)で管理している点から信頼できるかなと考えた（暗号系のパッケージは結構シビアだから）．&lt;/p&gt;
&lt;p&gt;このパッケージで何らかのハッシュ関数を利用するには &lt;code&gt;Crypto.Hash.hash&lt;/code&gt; 関数を利用すれば良い． アルゴリズム（MD5 か SHA256 かなど）は返り値の型を明示することで指定できる． 今回の場合は &lt;code&gt;Digest MD5&lt;/code&gt; 型とすれば良い:&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Crypto.Hash&lt;/span&gt; (&lt;span class="dt"&gt;Digest&lt;/span&gt;, &lt;span class="dt"&gt;MD5&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Crypto.Hash&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;Crypto&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fingerprint ::&lt;/span&gt; &lt;span class="dt"&gt;ByteString&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; (&lt;span class="dt"&gt;Digest&lt;/span&gt; &lt;span class="dt"&gt;MD5&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5"&gt;&lt;/a&gt;fingerprint content &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6"&gt;&lt;/a&gt;  body &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; pubkeyBody content&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7"&gt;&lt;/a&gt;  bin  &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; decode body&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; Crypto.hash bin&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="試す"&gt;試す&lt;/h2&gt;
&lt;p&gt;GHCi で適当に:&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;:&lt;/span&gt;set &lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dt"&gt;XOverloadedString&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2"&gt;&lt;/a&gt;&lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Crypto.SSH.PubKey&lt;/span&gt;      &lt;span class="co"&gt;-- 今まで定義してた関数のモジュール&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3"&gt;&lt;/a&gt;&lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt; fingerprint &lt;span class="st"&gt;&amp;quot;ssh-rsa AAAA...&amp;quot;&lt;/span&gt; &lt;span class="co"&gt;-- 適当に public key の中身を貼り付ける&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4"&gt;&lt;/a&gt;&lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;f3b17672020e4e8ad25516034facc12d&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;GitHub では8ビットごとに &lt;code&gt;:&lt;/code&gt; で区切られてるが，まぁそれはいいでしょ．&lt;/p&gt;
&lt;h2 id="おしまい"&gt;おしまい&lt;/h2&gt;
&lt;p&gt;意外とこういう Crypto 系のテーマの Haskell コードの例って少ないよね． 全部コード読んで試したよ．&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/01/05/215614</id><title type="text">rustでdiscordのbotを作ってみたくて下調べ(2)</title><updated>2020-01-05T21:56:14+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/01/05/215614"/><summary type="html">discord の bot を作るのなら websocket が必須なので下調べ。 というか、調べなくても discord-rs が使っていた websocket がそのまま使えるはずと思っていたのだが、開発が sluggish なので tokio-tungstenite を勧めている。良い名前空間を使っているだけに悲しい。 tokio-tungstenite の方は、 async/await への対応がまだであり、 鋭意作業中 のようだ。近日中にリリースされそうな勢い。 一方で、 crates.io で改めて検索すると、 ws なんてやつがいる。利用数は多いようだが、こいつは async/a…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2020/01/04/225431</id><title type="text">rustでdiscordのbotを作ってみたくて下調べ</title><updated>2020-01-04T22:54:31+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2020/01/04/225431"/><summary type="html">結論から書くとまだ何もしてない。 discord-rs というのがあるのだけど、だいぶ古い。特に嫌なのが issue にも上がっている通り openssl 1.0 系への依存。 昨年末にEOLを迎えている ので避けておきたい。 という事で手元でバージョンを上げようと試みたのだが、これがかなり厳しい。特に hyper 周りがバージョンが上がって大きくインタフェースが変わっており、変更量が多すぎて諦めた。ついでに edition も Rust 2018 にしようと試みたのだが、 try! の廃止があまりにもきつかったので断念。 cargo fix --edition を使えと書いてあったが、 tr…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2020/01/01/083723</id><title type="text">2019 年のスライド一挙公開、あるいは 2020 年の方針</title><updated>2020-01-01T08:54:55+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2020/01/01/083723"/><summary type="html">あけましておめでとうございます。2019 年は大変お世話になりました。2020 年も張り切っていきましょう。 さて、2019 年には結構な回数の外部発表を行いました。これらの発表内容のうち一部は単独のブログ記事としてまとめてありますが、機を逸してしまって記事化されていないものも相当数あります。そこで本記事では、2019 年中に行った発表を一覧としてまとめてみました。 2019 年の活動実績 2019 年の登壇は全部で 19 件でした。うち（先着や抽選ではなく）CFP に応募して採択されたものは 4 件です。 チェシャ猫が普段活動している領域は、Twitter の Bio にも書いてある通り、大…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2019/12/31/210000</id><title type="text">2019年を振り返って</title><updated>2019-12-31T21:51:33+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2019/12/31/210000"/><summary type="html">今年は仕事の部署異動があり気分一新したわけですが、思うようにパフォーマンスを出せず悩んでいたような気がします。前半もチームのために頑張っていた気がするんですがすべて忘れました。 今日は実家でgoreのGo modules対応をやってました。いい加減modules対応していないのやばいよなと思って一所懸命packagesパッケージのコードを読んでいます。まだ確認しないといけないパターンは沢山ありそうですが、年始にはマージする予定です (と書いて追い込んでおく)。goreは本当に便利なのでmodulesごときで死なせたくないですね… 今年はgojqを作れたのは大きいですね。これは本当にいいプロダク…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/12/30/231113</id><title type="text">2019年のまとめ</title><updated>2019-12-30T23:11:13+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/12/30/231113"/><summary type="html">今年を箇条書きでまとめておく。歳のせいか意識の高い話は何もなく、ああ、良くないなあとは思うのだが、まあそれとは別の話として、将来の自分用にメモを残して置くことはいいことだろう。 高脂血症の薬を飲み始め、肉食を再開する 禁酒、COMPは継続 副業を打ち切られる 息子が幼稚園に入る Rustを覚えて、書き始める Haskellを数行しか書かなかった 大学生の家庭教師を始める rarejob を始めるが体調不良により断念 atcoder を始めるが体調不良により断念 とにかくずっと風邪をひいている 親と苫小牧でキャンプ よく遊んだゲーム ディヴィニティオリジナル・シン２ Sekiro Disco E…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2019/12/25/100000</id><title type="text">GitHub Enterprise から GitHub への移行ツールをGoで作りました！</title><updated>2019-12-25T10:00:00+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2019/12/25/100000"/><summary type="html">弊社ではGitHub Enterprise (以下GHE) からGitHubへの移行が進んでいます。今年頭のプラン改変やGitHub Connect、ActionsやAppsの充実などGitHubの機能強化が後押しとなりました。GHEのメンテナンスコストも徐々に重荷になってきていました。 リポジトリを移行するにあたって問題となるのが、これまでの歴史をどこまで新リポジトリに移行するかということです。もちろんgitのログはそのまま移行できますが、以下のようなものも移行したいと言われると色々と考えることが出てきます。 issueやpull requestのコメントやレビュー、ラベル コードコメントか…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2019-12-22-json-parser-using-elixir.html</id><title type="text">Elixir による JSON Parser</title><updated>2019-12-22T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2019-12-22-json-parser-using-elixir.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;「&lt;a href="https://matsubara0507.github.io/posts/2019-12-08-re-create-thank-you-stars-ver-elixir.html"&gt;久しぶりに thank_you_stars をビルドする&lt;/a&gt;」の続きというかおまけというかって感じの記事です． この記事の最後で poison を抜いてお手製 JSON パーサーを組み込みました． 綺麗に整えたので記事にまとめる．&lt;/p&gt;
&lt;h2 id="実装する"&gt;実装する&lt;/h2&gt;
&lt;p&gt;外部パッケージを使えない縛りなので，完全な Pure Elixir で実装していく．&lt;/p&gt;
&lt;h3 id="result-型"&gt;Result 型&lt;/h3&gt;
&lt;p&gt;その前に便利モジュールを作っておく． いわゆる &lt;code&gt;Either&lt;/code&gt; 型だ．&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# Result e a = {:error, e} | {:ok, a} のような型を扱う&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defmodule&lt;/span&gt; &lt;span class="cn"&gt;ThankYouStars&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="cn"&gt;Result&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# {:ok, a}, {:error, e} をそのまま返す&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; success(v), &lt;span class="kw"&gt;do&lt;/span&gt;: {&lt;span class="va"&gt;:ok&lt;/span&gt;, v}&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; failure(v), &lt;span class="kw"&gt;do&lt;/span&gt;: {&lt;span class="va"&gt;:error&lt;/span&gt;, v}&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# {:ok, a} だった場合に {:ok, f(a)} を返す (f は a -&amp;gt; b)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; map({&lt;span class="va"&gt;:ok&lt;/span&gt;, v}, f), &lt;span class="kw"&gt;do&lt;/span&gt;: success(f&lt;span class="op"&gt;.&lt;/span&gt;(v))&lt;/span&gt;
&lt;span id="cb1-9"&gt;&lt;a href="#cb1-9"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; map(err &lt;span class="op"&gt;=&lt;/span&gt; {&lt;span class="va"&gt;:error&lt;/span&gt;, _}, _), &lt;span class="kw"&gt;do&lt;/span&gt;: err&lt;/span&gt;
&lt;span id="cb1-10"&gt;&lt;a href="#cb1-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-11"&gt;&lt;a href="#cb1-11"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# {:ok, a} だった場合に f(a) を返す (f は a -&amp;gt; Result e b)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-12"&gt;&lt;a href="#cb1-12"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; and_then({&lt;span class="va"&gt;:ok&lt;/span&gt;, v}, f), &lt;span class="kw"&gt;do&lt;/span&gt;: f&lt;span class="op"&gt;.&lt;/span&gt;(v)&lt;/span&gt;
&lt;span id="cb1-13"&gt;&lt;a href="#cb1-13"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; and_then(err &lt;span class="op"&gt;=&lt;/span&gt; {&lt;span class="va"&gt;:error&lt;/span&gt;, _}, _), &lt;span class="kw"&gt;do&lt;/span&gt;: err&lt;/span&gt;
&lt;span id="cb1-14"&gt;&lt;a href="#cb1-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-15"&gt;&lt;a href="#cb1-15"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# {:error, e} だった場合に {:error, f(e)} を返す (f は e -&amp;gt; b)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-16"&gt;&lt;a href="#cb1-16"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; map_error({&lt;span class="va"&gt;:error&lt;/span&gt;, e}, f), &lt;span class="kw"&gt;do&lt;/span&gt;: failure(f&lt;span class="op"&gt;.&lt;/span&gt;(e))&lt;/span&gt;
&lt;span id="cb1-17"&gt;&lt;a href="#cb1-17"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; map_error(r &lt;span class="op"&gt;=&lt;/span&gt; {&lt;span class="va"&gt;:ok&lt;/span&gt;, _}, _), &lt;span class="kw"&gt;do&lt;/span&gt;: r&lt;/span&gt;
&lt;span id="cb1-18"&gt;&lt;a href="#cb1-18"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これを作っておくと &lt;code&gt;{:ok, a} | {:error, e}&lt;/code&gt; なデータ型をパイプラインと組み合わせて利用できるようになる(実はプリミティブあったりしないよね？)．&lt;/p&gt;
&lt;h3 id="状態のデータ構造"&gt;状態のデータ構造&lt;/h3&gt;
&lt;p&gt;シンプルにパース結果と残りの文字列を保存する連想配列を持ち回ることにする:&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defmodule&lt;/span&gt; &lt;span class="cn"&gt;ThankYouStars&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="cn"&gt;JSON&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;  &lt;span class="im"&gt;alias&lt;/span&gt; &lt;span class="cn"&gt;ThankYouStars&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="cn"&gt;Result&lt;/span&gt;, &lt;span class="va"&gt;as:&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; decode(str) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5"&gt;&lt;/a&gt;    init_stat(str)&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; match_element() &lt;span class="co"&gt;# これがパーサー&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8"&gt;&lt;/a&gt;      &lt;span class="co"&gt;# パースが成功した場合 {:ok} かつ残り文字列が空になる想定&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9"&gt;&lt;/a&gt;      {&lt;span class="va"&gt;:ok&lt;/span&gt;, %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, &lt;span class="va"&gt;result:&lt;/span&gt; result}} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;success(result)&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="#cb2-10"&gt;&lt;/a&gt;      {_, %{&lt;span class="va"&gt;rest:&lt;/span&gt; rest}} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;failure(rest)&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="#cb2-11"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-12"&gt;&lt;a href="#cb2-12"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-13"&gt;&lt;a href="#cb2-13"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-14"&gt;&lt;a href="#cb2-14"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# rest が残り文字列で result がパース結果&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-15"&gt;&lt;a href="#cb2-15"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;defp&lt;/span&gt; init_stat(str), &lt;span class="kw"&gt;do&lt;/span&gt;: %{&lt;span class="va"&gt;rest:&lt;/span&gt; str, &lt;span class="va"&gt;result:&lt;/span&gt; %{}}&lt;/span&gt;
&lt;span id="cb2-16"&gt;&lt;a href="#cb2-16"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-17"&gt;&lt;a href="#cb2-17"&gt;&lt;/a&gt;  &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-18"&gt;&lt;a href="#cb2-18"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;今回実装する JSON パーサーは最終的に Elixir の連想配列や配列，真偽値や文字列などのプリミティブなデータ型へ変換することとする． なので，初期値として空の連想配列 &lt;code&gt;%{}&lt;/code&gt; を渡している．&lt;/p&gt;
&lt;h3 id="json.org"&gt;JSON.org&lt;/h3&gt;
&lt;p&gt;JSON の(基本的な)構文定義は &lt;a href="https://json.org"&gt;JSON.org&lt;/a&gt; に書いてある． ご丁寧に BNF が書いてあるので，これに沿って実装するだけだ． 例えば，こんな感じの BNF が記述されている:&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode txt"&gt;&lt;code class="sourceCode default"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;json&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt;  := element&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4"&gt;&lt;/a&gt;element&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5"&gt;&lt;/a&gt;  := ws value ws&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7"&gt;&lt;/a&gt;value&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8"&gt;&lt;/a&gt;  := object&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9"&gt;&lt;/a&gt;   | array&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10"&gt;&lt;/a&gt;   | string&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11"&gt;&lt;/a&gt;   | number&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12"&gt;&lt;/a&gt;   | &amp;quot;true&amp;quot;&lt;/span&gt;
&lt;span id="cb3-13"&gt;&lt;a href="#cb3-13"&gt;&lt;/a&gt;   | &amp;quot;false&amp;quot;&lt;/span&gt;
&lt;span id="cb3-14"&gt;&lt;a href="#cb3-14"&gt;&lt;/a&gt;   | &amp;quot;null&amp;quot;&lt;/span&gt;
&lt;span id="cb3-15"&gt;&lt;a href="#cb3-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-16"&gt;&lt;a href="#cb3-16"&gt;&lt;/a&gt;ws&lt;/span&gt;
&lt;span id="cb3-17"&gt;&lt;a href="#cb3-17"&gt;&lt;/a&gt;  := ... // 空白除去&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これをパターンマッチを駆使して実装するとこんな感じ:&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_element(stat) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2"&gt;&lt;/a&gt;  trim_leading(stat) &lt;span class="co"&gt;# rest の前方の空白を除去します&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; match_value()&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;map(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;trim_leading(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb4-5"&gt;&lt;a href="#cb4-5"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-6"&gt;&lt;a href="#cb4-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-7"&gt;&lt;a href="#cb4-7"&gt;&lt;/a&gt;&lt;span class="co"&gt;# match_string や match_array はあとで&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-8"&gt;&lt;a href="#cb4-8"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_value(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest}), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;success(%{&lt;span class="va"&gt;result:&lt;/span&gt; &lt;span class="cn"&gt;true&lt;/span&gt;, &lt;span class="va"&gt;rest:&lt;/span&gt; rest})&lt;/span&gt;
&lt;span id="cb4-9"&gt;&lt;a href="#cb4-9"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_value(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest}), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;success(%{&lt;span class="va"&gt;result:&lt;/span&gt; &lt;span class="cn"&gt;false&lt;/span&gt;, &lt;span class="va"&gt;rest:&lt;/span&gt; rest})&lt;/span&gt;
&lt;span id="cb4-10"&gt;&lt;a href="#cb4-10"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_value(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;null&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest}), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;success(%{&lt;span class="va"&gt;result:&lt;/span&gt; &lt;span class="cn"&gt;nil&lt;/span&gt;, &lt;span class="va"&gt;rest:&lt;/span&gt; rest})&lt;/span&gt;
&lt;span id="cb4-11"&gt;&lt;a href="#cb4-11"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_value(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; _}), &lt;span class="kw"&gt;do&lt;/span&gt;: match_string(stat)&lt;/span&gt;
&lt;span id="cb4-12"&gt;&lt;a href="#cb4-12"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_value(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;[&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; _}), &lt;span class="kw"&gt;do&lt;/span&gt;: match_array(stat)&lt;/span&gt;
&lt;span id="cb4-13"&gt;&lt;a href="#cb4-13"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_value(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;{&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; _}), &lt;span class="kw"&gt;do&lt;/span&gt;: match_object(stat)&lt;/span&gt;
&lt;span id="cb4-14"&gt;&lt;a href="#cb4-14"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_value(stat), &lt;span class="kw"&gt;do&lt;/span&gt;: match_number(stat)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;match_xxx&lt;/code&gt; 系の関数は全て前述した &lt;code&gt;Result e a&lt;/code&gt; 型を返すイメージ(&lt;code&gt;e&lt;/code&gt; も &lt;code&gt;a&lt;/code&gt; も前述した状態の連想配列だが)．&lt;/p&gt;
&lt;h3 id="オブジェクトのパース"&gt;オブジェクトのパース&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;{}&lt;/code&gt; で囲まれた連想配列のようなもの，例えば &lt;code&gt;{ &amp;quot;key&amp;quot; : true }&lt;/code&gt; がオブジェクトだ:&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode txt"&gt;&lt;code class="sourceCode default"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1"&gt;&lt;/a&gt;object&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2"&gt;&lt;/a&gt;  := &amp;#39;{&amp;#39; ws &amp;#39;}&amp;#39;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3"&gt;&lt;/a&gt;   | &amp;#39;{&amp;#39; members &amp;#39;}&amp;#39;&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5"&gt;&lt;/a&gt;members&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6"&gt;&lt;/a&gt;  := member&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7"&gt;&lt;/a&gt;   | member &amp;#39;,&amp;#39; members&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9"&gt;&lt;/a&gt;member&lt;/span&gt;
&lt;span id="cb5-10"&gt;&lt;a href="#cb5-10"&gt;&lt;/a&gt;  := ws string ws &amp;#39;:&amp;#39; element&lt;/span&gt;
&lt;span id="cb5-11"&gt;&lt;a href="#cb5-11"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-12"&gt;&lt;a href="#cb5-12"&gt;&lt;/a&gt;string&lt;/span&gt;
&lt;span id="cb5-13"&gt;&lt;a href="#cb5-13"&gt;&lt;/a&gt;  := ... // 文字列&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;文字列の部分はあとで実装するとして，他の部分だけをパターンマッチとパイプを利用して実装するとこんな感じ:&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# parse_when_unmatch_by(stat, char, parser) は&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2"&gt;&lt;/a&gt;&lt;span class="co"&gt;# char の文字列にマッチしなければ parser を実行し&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3"&gt;&lt;/a&gt;&lt;span class="co"&gt;# マッチした場合は parser を実行せずに stat をそのまま返す&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_object(stat) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5"&gt;&lt;/a&gt;  match_left_par(stat)                               &lt;span class="co"&gt;# `{` にマッチ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-6"&gt;&lt;a href="#cb6-6"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;map(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;trim_leading(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))                   &lt;span class="co"&gt;# 空白除去&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-7"&gt;&lt;a href="#cb6-7"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;update_stat(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;, &lt;span class="va"&gt;:result&lt;/span&gt;, %{})) &lt;span class="co"&gt;# 状態の result を空オブジェクト %{} に更新&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-8"&gt;&lt;a href="#cb6-8"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;parse_when_unmatch_by(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;, &lt;span class="st"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;, &lt;span class="kw"&gt;fn&lt;/span&gt; s &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; match_members(s) &lt;span class="kw"&gt;end&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb6-9"&gt;&lt;a href="#cb6-9"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_right_par(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))           &lt;span class="co"&gt;# `}` にマッチ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-10"&gt;&lt;a href="#cb6-10"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-11"&gt;&lt;a href="#cb6-11"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-12"&gt;&lt;a href="#cb6-12"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_members(stat) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-13"&gt;&lt;a href="#cb6-13"&gt;&lt;/a&gt;  match_member(stat)&lt;/span&gt;
&lt;span id="cb6-14"&gt;&lt;a href="#cb6-14"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_members_tail(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb6-15"&gt;&lt;a href="#cb6-15"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-16"&gt;&lt;a href="#cb6-16"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-17"&gt;&lt;a href="#cb6-17"&gt;&lt;/a&gt;&lt;span class="co"&gt;# match_members_tail は members の再帰処理をする&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-18"&gt;&lt;a href="#cb6-18"&gt;&lt;/a&gt;&lt;span class="co"&gt;# 先頭が `,` にマッチした時には再帰処理を行い&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-19"&gt;&lt;a href="#cb6-19"&gt;&lt;/a&gt;&lt;span class="co"&gt;# マッチしない場合は stat をそのまま返す&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-20"&gt;&lt;a href="#cb6-20"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_members_tail(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest}) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-21"&gt;&lt;a href="#cb6-21"&gt;&lt;/a&gt;  update_stat(stat, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb6-22"&gt;&lt;a href="#cb6-22"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_members(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb6-23"&gt;&lt;a href="#cb6-23"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-24"&gt;&lt;a href="#cb6-24"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_members_tail(stat), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;success(stat)&lt;/span&gt;
&lt;span id="cb6-25"&gt;&lt;a href="#cb6-25"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-26"&gt;&lt;a href="#cb6-26"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_member(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;result:&lt;/span&gt; prev}) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-27"&gt;&lt;a href="#cb6-27"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# 空白を除去してから文字列にマッチさせてみる&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-28"&gt;&lt;a href="#cb6-28"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;case&lt;/span&gt; match_string(trim_leading(stat)) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-29"&gt;&lt;a href="#cb6-29"&gt;&lt;/a&gt;    {&lt;span class="va"&gt;:error&lt;/span&gt;, stat} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-30"&gt;&lt;a href="#cb6-30"&gt;&lt;/a&gt;      &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;failure(stat)&lt;/span&gt;
&lt;span id="cb6-31"&gt;&lt;a href="#cb6-31"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-32"&gt;&lt;a href="#cb6-32"&gt;&lt;/a&gt;    &lt;span class="co"&gt;# string のパースに成功した場合にのみ，そのパース結果を `key` として残りをパースする&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-33"&gt;&lt;a href="#cb6-33"&gt;&lt;/a&gt;    {&lt;span class="va"&gt;:ok&lt;/span&gt;, stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;result:&lt;/span&gt; key}} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-34"&gt;&lt;a href="#cb6-34"&gt;&lt;/a&gt;      trim_leading(stat)&lt;/span&gt;
&lt;span id="cb6-35"&gt;&lt;a href="#cb6-35"&gt;&lt;/a&gt;      &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; match_colon() &lt;span class="co"&gt;# &amp;#39;:&amp;#39; にマッチ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-36"&gt;&lt;a href="#cb6-36"&gt;&lt;/a&gt;      &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_element(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)) &lt;span class="co"&gt;#match_element は前のと同じ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-37"&gt;&lt;a href="#cb6-37"&gt;&lt;/a&gt;      &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;modify_stat(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;, &lt;span class="va"&gt;:result&lt;/span&gt;, &lt;span class="kw"&gt;fn&lt;/span&gt; v &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Map&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;put(prev, key, v) &lt;span class="kw"&gt;end&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb6-38"&gt;&lt;a href="#cb6-38"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-39"&gt;&lt;a href="#cb6-39"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;update_stat(stat, key, value)&lt;/code&gt; は &lt;code&gt;stat&lt;/code&gt; の &lt;code&gt;key&lt;/code&gt; を &lt;code&gt;value&lt;/code&gt; で置き換える関数で，&lt;code&gt;modify_stat(stat, key, func)&lt;/code&gt; は &lt;code&gt;stat&lt;/code&gt; の &lt;code&gt;key&lt;/code&gt; を &lt;code&gt;func&lt;/code&gt; で更新する関数だ．&lt;/p&gt;
&lt;p&gt;余談だが，Elixir は(僕が思うに)普通の関数それ自体は第一級では無いが，無名関数 &lt;code&gt;fn args -&amp;gt; ... end&lt;/code&gt; は第一級のようだ． &lt;code&gt;&amp;amp;any_function(&amp;amp;1, &amp;amp;2)&lt;/code&gt; などとすることで &lt;code&gt;fn arg1 arg2 -&amp;gt; any_function(arg1, arg2) end&lt;/code&gt; の糖衣構文になるっぽく，関数を関数の引数に渡す場合はこうするらしい． ただし，この記法は入れ子にできないので，&lt;code&gt;modify_stat&lt;/code&gt; や &lt;code&gt;parse_when_unmatch_by&lt;/code&gt; では内部の方の関数を &lt;code&gt;fn args -&amp;gt; ... end&lt;/code&gt; で直接囲っている(&lt;a href="https://stackoverflow.com/questions/38217426/can-i-nest-anonymous-functions-in-elixir"&gt;参照&lt;/a&gt;)．&lt;/p&gt;
&lt;h3 id="配列のパース"&gt;配列のパース&lt;/h3&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode txt"&gt;&lt;code class="sourceCode default"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1"&gt;&lt;/a&gt;array&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2"&gt;&lt;/a&gt;  := &amp;#39;[&amp;#39; ws &amp;#39;]&amp;#39;&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3"&gt;&lt;/a&gt;   | &amp;#39;[&amp;#39; elements &amp;#39;]&amp;#39;&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5"&gt;&lt;/a&gt;elements&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6"&gt;&lt;/a&gt;  := element&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="#cb7-7"&gt;&lt;/a&gt;   | element &amp;#39;,&amp;#39; elements&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;実は &lt;code&gt;{}&lt;/code&gt; が &lt;code&gt;[]&lt;/code&gt; になっただけで，だいたいオブジェクトと同じだ:&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_array(stat) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2"&gt;&lt;/a&gt;  match_left_square(stat)                           &lt;span class="co"&gt;# &amp;#39;[&amp;#39; にマッチ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;map(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;trim_leading(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))                  &lt;span class="co"&gt;# 空白除去&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;update_stat(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;, &lt;span class="va"&gt;:result&lt;/span&gt;, [])) &lt;span class="co"&gt;# 状態の result を空配列 [] に更新&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;parse_when_unmatch_by(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;, &lt;span class="st"&gt;&amp;quot;]&amp;quot;&lt;/span&gt;, &lt;span class="kw"&gt;fn&lt;/span&gt; s &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; match_elements(s) &lt;span class="kw"&gt;end&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb8-6"&gt;&lt;a href="#cb8-6"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_right_square(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))       &lt;span class="co"&gt;# &amp;#39;]&amp;#39; にマッチ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-7"&gt;&lt;a href="#cb8-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-8"&gt;&lt;a href="#cb8-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-9"&gt;&lt;a href="#cb8-9"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_elements(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;result:&lt;/span&gt; prev}) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-10"&gt;&lt;a href="#cb8-10"&gt;&lt;/a&gt;  match_element(stat)&lt;/span&gt;
&lt;span id="cb8-11"&gt;&lt;a href="#cb8-11"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# ここで状態(配列)の更新をしてる点だけが違う&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-12"&gt;&lt;a href="#cb8-12"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;modify_stat(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;, &lt;span class="va"&gt;:result&lt;/span&gt;, &lt;span class="kw"&gt;fn&lt;/span&gt; v &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; prev &lt;span class="op"&gt;++&lt;/span&gt; [v] &lt;span class="kw"&gt;end&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb8-13"&gt;&lt;a href="#cb8-13"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_elements_tail(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb8-14"&gt;&lt;a href="#cb8-14"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-15"&gt;&lt;a href="#cb8-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-16"&gt;&lt;a href="#cb8-16"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_elements_tail(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest}) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-17"&gt;&lt;a href="#cb8-17"&gt;&lt;/a&gt;  update_stat(stat, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb8-18"&gt;&lt;a href="#cb8-18"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_elements(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb8-19"&gt;&lt;a href="#cb8-19"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-20"&gt;&lt;a href="#cb8-20"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_elements_tail(stat), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;success(stat)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="文字列のパース"&gt;文字列のパース&lt;/h3&gt;
&lt;p&gt;さぁこっからが大変． 文字列内でのエスケープをそれっぽく処理する必要がある:&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_string(stat) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-2"&gt;&lt;a href="#cb9-2"&gt;&lt;/a&gt;  match_double_quote(stat)                          &lt;span class="co"&gt;# &amp;#39;&amp;quot;&amp;#39; にマッチ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-3"&gt;&lt;a href="#cb9-3"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;update_stat(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;, &lt;span class="va"&gt;:result&lt;/span&gt;, &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)) &lt;span class="co"&gt;# 状態の result を空文字列 &amp;quot;&amp;quot; に更新&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-4"&gt;&lt;a href="#cb9-4"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_characters(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb9-5"&gt;&lt;a href="#cb9-5"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_double_quote(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))       &lt;span class="co"&gt;# &amp;#39;&amp;quot;&amp;#39; にマッチ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-6"&gt;&lt;a href="#cb9-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-7"&gt;&lt;a href="#cb9-7"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-8"&gt;&lt;a href="#cb9-8"&gt;&lt;/a&gt;&lt;span class="co"&gt;# どう見ても成功じゃ無いがどーせ後々エラーになるので...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-9"&gt;&lt;a href="#cb9-9"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_characters(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;}), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;success(stat)&lt;/span&gt;
&lt;span id="cb9-10"&gt;&lt;a href="#cb9-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-11"&gt;&lt;a href="#cb9-11"&gt;&lt;/a&gt;&lt;span class="co"&gt;# &amp;#39;&amp;quot;&amp;#39; にマッチしたら終わり&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-12"&gt;&lt;a href="#cb9-12"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_characters(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; _}), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;success(stat)&lt;/span&gt;
&lt;span id="cb9-13"&gt;&lt;a href="#cb9-13"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_characters(stat) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-14"&gt;&lt;a href="#cb9-14"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# &amp;quot;\&amp;quot; はエスケープ文字として処理する必要があるのでまずはそれ以外&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-15"&gt;&lt;a href="#cb9-15"&gt;&lt;/a&gt;  parse_when_unmatch_by(stat, &lt;span class="st"&gt;&amp;quot;\\&amp;quot;&lt;/span&gt;, &lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_noescape_characters(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb9-16"&gt;&lt;a href="#cb9-16"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_escape(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;))     &lt;span class="co"&gt;# 次にエスケープ文字の処理&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-17"&gt;&lt;a href="#cb9-17"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;and_then(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;match_characters(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)) &lt;span class="co"&gt;# 再帰する&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-18"&gt;&lt;a href="#cb9-18"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;関数名の通り，&lt;code&gt;match_noescape_characters&lt;/code&gt; がエスケープ文字以外のパーサーで，&lt;code&gt;match_escape&lt;/code&gt; がエスケープ文字のパーサーだ． &lt;code&gt;match_noescape_characters&lt;/code&gt; ではまず &lt;code&gt;\&lt;/code&gt; や &lt;code&gt;&amp;quot;&lt;/code&gt; を含まない文字列をマッチさせたい． しかし，パターンマッチは exclude なマッチはできないので，あんまり良く無いが正規表現でサボることにする:&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# エスケープされてない文字はダメっぽい&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_noescape_characters(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; _}), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;failure(stat)&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="#cb10-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_noescape_characters(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\t&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; _}), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;failure(stat)&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="#cb10-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_noescape_characters(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\u0000&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; _}), &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;failure(stat)&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="#cb10-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="#cb10-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_noescape_characters(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;result:&lt;/span&gt; prev}) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="#cb10-7"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# 名前付きキャプチャ，便利&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-8"&gt;&lt;a href="#cb10-8"&gt;&lt;/a&gt;  %{&lt;span class="st"&gt;&amp;quot;body&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; body, &lt;span class="st"&gt;&amp;quot;rest&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; rest} &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-9"&gt;&lt;a href="#cb10-9"&gt;&lt;/a&gt;    &lt;span class="cn"&gt;Regex&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;named_captures(&lt;span class="op"&gt;~&lt;/span&gt;r&lt;span class="op"&gt;/&lt;/span&gt;(?&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;body&lt;span class="op"&gt;&amp;gt;&lt;/span&gt;[&lt;span class="op"&gt;^&lt;/span&gt;\\\&lt;span class="st"&gt;&amp;quot;\n\x00\t]*)(?&amp;lt;rest&amp;gt;.*)/s, stat[:rest])&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-10"&gt;&lt;a href="#cb10-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-11"&gt;&lt;a href="#cb10-11"&gt;&lt;/a&gt;&lt;span class="st"&gt;  update_stat(%{result: prev &amp;lt;&amp;gt; body}, :rest, rest)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-12"&gt;&lt;a href="#cb10-12"&gt;&lt;/a&gt;&lt;span class="st"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;エスケープ文字は，もうパターンマッチで頑張る:&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_escape(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest, &lt;span class="va"&gt;result:&lt;/span&gt; prev}),&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;do&lt;/span&gt;: update_stat(%{&lt;span class="va"&gt;result:&lt;/span&gt; prev &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;}, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb11-3"&gt;&lt;a href="#cb11-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-4"&gt;&lt;a href="#cb11-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_escape(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\\\&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest, &lt;span class="va"&gt;result:&lt;/span&gt; prev}),&lt;/span&gt;
&lt;span id="cb11-5"&gt;&lt;a href="#cb11-5"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;do&lt;/span&gt;: update_stat(%{&lt;span class="va"&gt;result:&lt;/span&gt; prev &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\&amp;quot;&lt;/span&gt;}, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb11-6"&gt;&lt;a href="#cb11-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-7"&gt;&lt;a href="#cb11-7"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_escape(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\\/&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest, &lt;span class="va"&gt;result:&lt;/span&gt; prev}),&lt;/span&gt;
&lt;span id="cb11-8"&gt;&lt;a href="#cb11-8"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;do&lt;/span&gt;: update_stat(%{&lt;span class="va"&gt;result:&lt;/span&gt; prev &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\/&amp;quot;&lt;/span&gt;}, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb11-9"&gt;&lt;a href="#cb11-9"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-10"&gt;&lt;a href="#cb11-10"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_escape(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\b&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest, &lt;span class="va"&gt;result:&lt;/span&gt; prev}),&lt;/span&gt;
&lt;span id="cb11-11"&gt;&lt;a href="#cb11-11"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;do&lt;/span&gt;: update_stat(%{&lt;span class="va"&gt;result:&lt;/span&gt; prev &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\b&amp;quot;&lt;/span&gt;}, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb11-12"&gt;&lt;a href="#cb11-12"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-13"&gt;&lt;a href="#cb11-13"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_escape(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\f&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest, &lt;span class="va"&gt;result:&lt;/span&gt; prev}),&lt;/span&gt;
&lt;span id="cb11-14"&gt;&lt;a href="#cb11-14"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;do&lt;/span&gt;: update_stat(%{&lt;span class="va"&gt;result:&lt;/span&gt; prev &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\f&amp;quot;&lt;/span&gt;}, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb11-15"&gt;&lt;a href="#cb11-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-16"&gt;&lt;a href="#cb11-16"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_escape(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\n&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest, &lt;span class="va"&gt;result:&lt;/span&gt; prev}),&lt;/span&gt;
&lt;span id="cb11-17"&gt;&lt;a href="#cb11-17"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;do&lt;/span&gt;: update_stat(%{&lt;span class="va"&gt;result:&lt;/span&gt; prev &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;}, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb11-18"&gt;&lt;a href="#cb11-18"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-19"&gt;&lt;a href="#cb11-19"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_escape(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\r&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest, &lt;span class="va"&gt;result:&lt;/span&gt; prev}),&lt;/span&gt;
&lt;span id="cb11-20"&gt;&lt;a href="#cb11-20"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;do&lt;/span&gt;: update_stat(%{&lt;span class="va"&gt;result:&lt;/span&gt; prev &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\r&amp;quot;&lt;/span&gt;}, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb11-21"&gt;&lt;a href="#cb11-21"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-22"&gt;&lt;a href="#cb11-22"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_escape(%{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\t&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest, &lt;span class="va"&gt;result:&lt;/span&gt; prev}),&lt;/span&gt;
&lt;span id="cb11-23"&gt;&lt;a href="#cb11-23"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;do&lt;/span&gt;: update_stat(%{&lt;span class="va"&gt;result:&lt;/span&gt; prev &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\t&amp;quot;&lt;/span&gt;}, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb11-24"&gt;&lt;a href="#cb11-24"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-25"&gt;&lt;a href="#cb11-25"&gt;&lt;/a&gt;&lt;span class="co"&gt;# \u1234 とかいうやつ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-26"&gt;&lt;a href="#cb11-26"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_escape(stat &lt;span class="op"&gt;=&lt;/span&gt; %{&lt;span class="va"&gt;rest:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\u&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; rest, &lt;span class="va"&gt;result:&lt;/span&gt; prev}) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-27"&gt;&lt;a href="#cb11-27"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# /.{n,m}/ で n 個以上 m 個以下にマッチする&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-28"&gt;&lt;a href="#cb11-28"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;case&lt;/span&gt; &lt;span class="cn"&gt;Regex&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;named_captures(&lt;span class="op"&gt;~&lt;/span&gt;r&lt;span class="op"&gt;/&lt;/span&gt;(?&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;body&lt;span class="op"&gt;&amp;gt;&lt;/span&gt;[\dA&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="cn"&gt;Fa&lt;/span&gt;&lt;span class="op"&gt;-&lt;/span&gt;f]{&lt;span class="dv"&gt;4&lt;/span&gt;,&lt;span class="dv"&gt;4&lt;/span&gt;})(?&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;rest&lt;span class="op"&gt;&amp;gt;.*&lt;/span&gt;)&lt;span class="op"&gt;/&lt;/span&gt;s, rest) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-29"&gt;&lt;a href="#cb11-29"&gt;&lt;/a&gt;    %{&lt;span class="st"&gt;&amp;quot;body&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; body, &lt;span class="st"&gt;&amp;quot;rest&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; rest} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-30"&gt;&lt;a href="#cb11-30"&gt;&lt;/a&gt;      &lt;span class="co"&gt;# 4桁の16進数をエスケープされた文字列として変換する&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-31"&gt;&lt;a href="#cb11-31"&gt;&lt;/a&gt;      &lt;span class="co"&gt;# 変換できなかった場合は nil が返ってくる&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-32"&gt;&lt;a href="#cb11-32"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;case&lt;/span&gt; hex_to_string(body) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-33"&gt;&lt;a href="#cb11-33"&gt;&lt;/a&gt;        &lt;span class="cn"&gt;nil&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;failure(stat)&lt;/span&gt;
&lt;span id="cb11-34"&gt;&lt;a href="#cb11-34"&gt;&lt;/a&gt;        hex &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; update_stat(%{&lt;span class="va"&gt;result:&lt;/span&gt; prev &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; hex}, &lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb11-35"&gt;&lt;a href="#cb11-35"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-36"&gt;&lt;a href="#cb11-36"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-37"&gt;&lt;a href="#cb11-37"&gt;&lt;/a&gt;    _ &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-38"&gt;&lt;a href="#cb11-38"&gt;&lt;/a&gt;      &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;failure(stat)&lt;/span&gt;
&lt;span id="cb11-39"&gt;&lt;a href="#cb11-39"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-40"&gt;&lt;a href="#cb11-40"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-41"&gt;&lt;a href="#cb11-41"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-42"&gt;&lt;a href="#cb11-42"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; hex_to_string(str) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-43"&gt;&lt;a href="#cb11-43"&gt;&lt;/a&gt;  &lt;span class="cf"&gt;try&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-44"&gt;&lt;a href="#cb11-44"&gt;&lt;/a&gt;    &lt;span class="co"&gt;# 文字列を16進数として int 型に変換&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-45"&gt;&lt;a href="#cb11-45"&gt;&lt;/a&gt;    {hex, _} &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="cn"&gt;Integer&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;parse(str, &lt;span class="dv"&gt;16&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb11-46"&gt;&lt;a href="#cb11-46"&gt;&lt;/a&gt;    &lt;span class="op"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="va"&gt;hex::utf8&lt;/span&gt;&lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="co"&gt;# こういう記法で int を16進数でエスケープされた文字列に変換できる&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-47"&gt;&lt;a href="#cb11-47"&gt;&lt;/a&gt;  &lt;span class="cf"&gt;rescue&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-48"&gt;&lt;a href="#cb11-48"&gt;&lt;/a&gt;    _ &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;nil&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-49"&gt;&lt;a href="#cb11-49"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-50"&gt;&lt;a href="#cb11-50"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;まぁ正直，色々と雑で漏れてるケースもきっとあるのだが，そんな変な JSON をパースしたいわけでは無いのでこれでいいかな．&lt;/p&gt;
&lt;h3 id="数値のパース"&gt;数値のパース&lt;/h3&gt;
&lt;p&gt;数値は，マイナス符号・整数・浮動小数点数・&lt;code&gt;e&lt;/code&gt;記法を網羅する必要がある． これも，めんどくさいので正規表現に頼っちゃう:&lt;/p&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb12-1"&gt;&lt;a href="#cb12-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defp&lt;/span&gt; match_number(stat) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="#cb12-2"&gt;&lt;/a&gt;  {value, rest} &lt;span class="op"&gt;=&lt;/span&gt; compile_number(stat[&lt;span class="va"&gt;:rest&lt;/span&gt;])&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="#cb12-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-4"&gt;&lt;a href="#cb12-4"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# 文字列から数値を取得できなかった場合は nil が返ってくる&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-5"&gt;&lt;a href="#cb12-5"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;case&lt;/span&gt; value &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-6"&gt;&lt;a href="#cb12-6"&gt;&lt;/a&gt;    &lt;span class="cn"&gt;nil&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-7"&gt;&lt;a href="#cb12-7"&gt;&lt;/a&gt;      &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;failure(stat)&lt;/span&gt;
&lt;span id="cb12-8"&gt;&lt;a href="#cb12-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-9"&gt;&lt;a href="#cb12-9"&gt;&lt;/a&gt;    _ &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-10"&gt;&lt;a href="#cb12-10"&gt;&lt;/a&gt;      &lt;span class="cn"&gt;Map&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;put(stat, &lt;span class="va"&gt;:result&lt;/span&gt;, value)&lt;/span&gt;
&lt;span id="cb12-11"&gt;&lt;a href="#cb12-11"&gt;&lt;/a&gt;      &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Map&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;put(&lt;span class="va"&gt;:rest&lt;/span&gt;, rest)&lt;/span&gt;
&lt;span id="cb12-12"&gt;&lt;a href="#cb12-12"&gt;&lt;/a&gt;      &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;success()&lt;/span&gt;
&lt;span id="cb12-13"&gt;&lt;a href="#cb12-13"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-14"&gt;&lt;a href="#cb12-14"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-15"&gt;&lt;a href="#cb12-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-16"&gt;&lt;a href="#cb12-16"&gt;&lt;/a&gt;&lt;span class="kw"&gt;def&lt;/span&gt; compile_number(str) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-17"&gt;&lt;a href="#cb12-17"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# 名前付きキャプチャ，超便利&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-18"&gt;&lt;a href="#cb12-18"&gt;&lt;/a&gt;  &lt;span class="co"&gt;# minus は `-`，digit は整数部，frac は小数点以下，exp は `e`記法 (`10e-2`とか)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-19"&gt;&lt;a href="#cb12-19"&gt;&lt;/a&gt;  %{&lt;span class="st"&gt;&amp;quot;minus&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; minus, &lt;span class="st"&gt;&amp;quot;digit&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; digit, &lt;span class="st"&gt;&amp;quot;frac&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; frac, &lt;span class="st"&gt;&amp;quot;exp&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; exp, &lt;span class="st"&gt;&amp;quot;rest&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; rest} &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-20"&gt;&lt;a href="#cb12-20"&gt;&lt;/a&gt;    &lt;span class="cn"&gt;Regex&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;named_captures(&lt;/span&gt;
&lt;span id="cb12-21"&gt;&lt;a href="#cb12-21"&gt;&lt;/a&gt;      &lt;span class="op"&gt;~&lt;/span&gt;r&lt;span class="op"&gt;/&lt;/span&gt;(?&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;minus&lt;span class="op"&gt;&amp;gt;-&lt;/span&gt;?)(?&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;digit&lt;span class="op"&gt;&amp;gt;&lt;/span&gt;[[&lt;span class="va"&gt;:digit&lt;/span&gt;:]]&lt;span class="op"&gt;*&lt;/span&gt;)(?&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;frac&lt;span class="op"&gt;&amp;gt;&lt;/span&gt;\&lt;span class="op"&gt;.&lt;/span&gt;?[[&lt;span class="va"&gt;:digit&lt;/span&gt;:]]&lt;span class="op"&gt;*&lt;/span&gt;)(?&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;exp&lt;span class="op"&gt;&amp;gt;&lt;/span&gt;[eE]?[&lt;span class="op"&gt;-+&lt;/span&gt;]?[[&lt;span class="va"&gt;:digit&lt;/span&gt;:]]&lt;span class="op"&gt;*&lt;/span&gt;)(?&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;rest&lt;span class="op"&gt;&amp;gt;.*&lt;/span&gt;)&lt;span class="op"&gt;/&lt;/span&gt;s,&lt;/span&gt;
&lt;span id="cb12-22"&gt;&lt;a href="#cb12-22"&gt;&lt;/a&gt;      str&lt;/span&gt;
&lt;span id="cb12-23"&gt;&lt;a href="#cb12-23"&gt;&lt;/a&gt;    )&lt;/span&gt;
&lt;span id="cb12-24"&gt;&lt;a href="#cb12-24"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-25"&gt;&lt;a href="#cb12-25"&gt;&lt;/a&gt;  value &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-26"&gt;&lt;a href="#cb12-26"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;case&lt;/span&gt; {digit, frac, exp} &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-27"&gt;&lt;a href="#cb12-27"&gt;&lt;/a&gt;      {&lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, _, _} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-28"&gt;&lt;a href="#cb12-28"&gt;&lt;/a&gt;        &lt;span class="cn"&gt;nil&lt;/span&gt; &lt;span class="co"&gt;# 整数部が無い場合はダメ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-29"&gt;&lt;a href="#cb12-29"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-30"&gt;&lt;a href="#cb12-30"&gt;&lt;/a&gt;      {&lt;span class="st"&gt;&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; num, &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;} &lt;span class="kw"&gt;when&lt;/span&gt; num&lt;span class="op"&gt; !=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-31"&gt;&lt;a href="#cb12-31"&gt;&lt;/a&gt;        &lt;span class="cn"&gt;nil&lt;/span&gt; &lt;span class="co"&gt;# 0 から始まる整数もダメ(小数はOK)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-32"&gt;&lt;a href="#cb12-32"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-33"&gt;&lt;a href="#cb12-33"&gt;&lt;/a&gt;      {_, &lt;span class="st"&gt;&amp;quot;.&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; num, _} &lt;span class="kw"&gt;when&lt;/span&gt; num &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-34"&gt;&lt;a href="#cb12-34"&gt;&lt;/a&gt;        &lt;span class="cn"&gt;nil&lt;/span&gt; &lt;span class="co"&gt;# 小数点だけはダメ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-35"&gt;&lt;a href="#cb12-35"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-36"&gt;&lt;a href="#cb12-36"&gt;&lt;/a&gt;      {_, _, &lt;span class="st"&gt;&amp;quot;e&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; num} &lt;span class="kw"&gt;when&lt;/span&gt; num &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-37"&gt;&lt;a href="#cb12-37"&gt;&lt;/a&gt;        &lt;span class="cn"&gt;nil&lt;/span&gt; &lt;span class="co"&gt;# e だけはダメ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-38"&gt;&lt;a href="#cb12-38"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-39"&gt;&lt;a href="#cb12-39"&gt;&lt;/a&gt;      {_, _, &lt;span class="st"&gt;&amp;quot;E&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; num} &lt;span class="kw"&gt;when&lt;/span&gt; num &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-40"&gt;&lt;a href="#cb12-40"&gt;&lt;/a&gt;        &lt;span class="cn"&gt;nil&lt;/span&gt; &lt;span class="co"&gt;# E だけはダメ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-41"&gt;&lt;a href="#cb12-41"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-42"&gt;&lt;a href="#cb12-42"&gt;&lt;/a&gt;      {_, &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="co"&gt;# これは整数の場合&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-43"&gt;&lt;a href="#cb12-43"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;case&lt;/span&gt; &lt;span class="cn"&gt;Integer&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;parse(minus &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; digit) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-44"&gt;&lt;a href="#cb12-44"&gt;&lt;/a&gt;          {num, &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; num&lt;/span&gt;
&lt;span id="cb12-45"&gt;&lt;a href="#cb12-45"&gt;&lt;/a&gt;          _ &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;nil&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-46"&gt;&lt;a href="#cb12-46"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-47"&gt;&lt;a href="#cb12-47"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-48"&gt;&lt;a href="#cb12-48"&gt;&lt;/a&gt;      _ &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="co"&gt;# これは浮動小数点数の場合&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-49"&gt;&lt;a href="#cb12-49"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;case&lt;/span&gt; &lt;span class="cn"&gt;Float&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;parse(minus &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; digit &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; frac &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; exp) &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-50"&gt;&lt;a href="#cb12-50"&gt;&lt;/a&gt;          {num, &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; num&lt;/span&gt;
&lt;span id="cb12-51"&gt;&lt;a href="#cb12-51"&gt;&lt;/a&gt;          _ &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;nil&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-52"&gt;&lt;a href="#cb12-52"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-53"&gt;&lt;a href="#cb12-53"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-54"&gt;&lt;a href="#cb12-54"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-55"&gt;&lt;a href="#cb12-55"&gt;&lt;/a&gt;  {value, rest}&lt;/span&gt;
&lt;span id="cb12-56"&gt;&lt;a href="#cb12-56"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これでとりあえず完成．&lt;/p&gt;
&lt;h2 id="テストする"&gt;テストする&lt;/h2&gt;
&lt;p&gt;JSON のテストスイートとして &lt;a href="https://github.com/nst/JSONTestSuite"&gt;nst/JSONTestSuite&lt;/a&gt; と言うのがあるので使わせてもらう． こんな感じに配置する:&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode txt"&gt;&lt;code class="sourceCode default"&gt;&lt;span id="cb13-1"&gt;&lt;a href="#cb13-1"&gt;&lt;/a&gt;\&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="#cb13-2"&gt;&lt;/a&gt;|- lib // elixir のコード置き場&lt;/span&gt;
&lt;span id="cb13-3"&gt;&lt;a href="#cb13-3"&gt;&lt;/a&gt;|- test&lt;/span&gt;
&lt;span id="cb13-4"&gt;&lt;a href="#cb13-4"&gt;&lt;/a&gt;|  |- fixture&lt;/span&gt;
&lt;span id="cb13-5"&gt;&lt;a href="#cb13-5"&gt;&lt;/a&gt;|  |  \- test_parsing // JSONTestSuite のテスト用 JSON ファイル群&lt;/span&gt;
&lt;span id="cb13-6"&gt;&lt;a href="#cb13-6"&gt;&lt;/a&gt;|  \- json_spec.exs&lt;/span&gt;
&lt;span id="cb13-7"&gt;&lt;a href="#cb13-7"&gt;&lt;/a&gt;\- mix.exs&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;テストには espec を使ってこんな感じに記述した:&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode elixir"&gt;&lt;code class="sourceCode elixir"&gt;&lt;span id="cb14-1"&gt;&lt;a href="#cb14-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# json_spec.exs&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="#cb14-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defmodule&lt;/span&gt; &lt;span class="cn"&gt;JSONSuite&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="#cb14-3"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;def&lt;/span&gt; test_suite &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-4"&gt;&lt;a href="#cb14-4"&gt;&lt;/a&gt;    [&lt;/span&gt;
&lt;span id="cb14-5"&gt;&lt;a href="#cb14-5"&gt;&lt;/a&gt;      &lt;span class="co"&gt;# エラーケース&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-6"&gt;&lt;a href="#cb14-6"&gt;&lt;/a&gt;      {&lt;span class="st"&gt;&amp;quot;n_array_1_true_without_comma.json&amp;quot;&lt;/span&gt;, {&lt;span class="va"&gt;:error&lt;/span&gt;, &lt;span class="cn"&gt;nil&lt;/span&gt;}},&lt;/span&gt;
&lt;span id="cb14-7"&gt;&lt;a href="#cb14-7"&gt;&lt;/a&gt;      {&lt;span class="st"&gt;&amp;quot;n_array_a_invalid_utf8.json&amp;quot;&lt;/span&gt;, {&lt;span class="va"&gt;:error&lt;/span&gt;, &lt;span class="cn"&gt;nil&lt;/span&gt;}},&lt;/span&gt;
&lt;span id="cb14-8"&gt;&lt;a href="#cb14-8"&gt;&lt;/a&gt;      &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-9"&gt;&lt;a href="#cb14-9"&gt;&lt;/a&gt;      &lt;span class="co"&gt;# 成功ケース&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-10"&gt;&lt;a href="#cb14-10"&gt;&lt;/a&gt;      {&lt;span class="st"&gt;&amp;quot;y_array_arraysWithSpaces.json&amp;quot;&lt;/span&gt;, {&lt;span class="va"&gt;:ok&lt;/span&gt;, [[]]}},&lt;/span&gt;
&lt;span id="cb14-11"&gt;&lt;a href="#cb14-11"&gt;&lt;/a&gt;      {&lt;span class="st"&gt;&amp;quot;y_array_empty-string.json&amp;quot;&lt;/span&gt;, {&lt;span class="va"&gt;:ok&lt;/span&gt;, [&lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;]}},&lt;/span&gt;
&lt;span id="cb14-12"&gt;&lt;a href="#cb14-12"&gt;&lt;/a&gt;      &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-13"&gt;&lt;a href="#cb14-13"&gt;&lt;/a&gt;    ]&lt;/span&gt;
&lt;span id="cb14-14"&gt;&lt;a href="#cb14-14"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-15"&gt;&lt;a href="#cb14-15"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-16"&gt;&lt;a href="#cb14-16"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-17"&gt;&lt;a href="#cb14-17"&gt;&lt;/a&gt;&lt;span class="co"&gt;# JSONSuite を先に宣言しないと使えなかった&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-18"&gt;&lt;a href="#cb14-18"&gt;&lt;/a&gt;&lt;span class="kw"&gt;defmodule&lt;/span&gt; &lt;span class="cn"&gt;JSONSpec&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-19"&gt;&lt;a href="#cb14-19"&gt;&lt;/a&gt;  &lt;span class="im"&gt;use&lt;/span&gt; &lt;span class="cn"&gt;ESpec&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-20"&gt;&lt;a href="#cb14-20"&gt;&lt;/a&gt;  &lt;span class="im"&gt;alias&lt;/span&gt; &lt;span class="cn"&gt;ThankYouStars&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="cn"&gt;JSON&lt;/span&gt;, &lt;span class="va"&gt;as:&lt;/span&gt; &lt;span class="cn"&gt;JSON&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-21"&gt;&lt;a href="#cb14-21"&gt;&lt;/a&gt;  &lt;span class="im"&gt;alias&lt;/span&gt; &lt;span class="cn"&gt;ThankYouStars&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="cn"&gt;Result&lt;/span&gt;, &lt;span class="va"&gt;as:&lt;/span&gt; &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-22"&gt;&lt;a href="#cb14-22"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-23"&gt;&lt;a href="#cb14-23"&gt;&lt;/a&gt;  describe &lt;span class="st"&gt;&amp;quot;JSON.decode&amp;quot;&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-24"&gt;&lt;a href="#cb14-24"&gt;&lt;/a&gt;    &lt;span class="cn"&gt;Enum&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;map(&lt;span class="cn"&gt;JSONSuite&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;test_suite(), &lt;span class="kw"&gt;fn&lt;/span&gt; {path, result} &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-25"&gt;&lt;a href="#cb14-25"&gt;&lt;/a&gt;      context path &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-26"&gt;&lt;a href="#cb14-26"&gt;&lt;/a&gt;        &lt;span class="co"&gt;# 変数を利用するには unquote する必要がある(マクロのせい？)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-27"&gt;&lt;a href="#cb14-27"&gt;&lt;/a&gt;        let(&lt;span class="va"&gt;:json&lt;/span&gt;, &lt;span class="kw"&gt;do&lt;/span&gt;: &lt;span class="cn"&gt;File&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;read!(&lt;span class="st"&gt;&amp;quot;test/fixture/test_parsing/&lt;/span&gt;&lt;span class="ot"&gt;#{&lt;/span&gt;&lt;span class="kw"&gt;unquote&lt;/span&gt;(path)&lt;span class="ot"&gt;}&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb14-28"&gt;&lt;a href="#cb14-28"&gt;&lt;/a&gt;        it(&lt;/span&gt;
&lt;span id="cb14-29"&gt;&lt;a href="#cb14-29"&gt;&lt;/a&gt;          &lt;span class="kw"&gt;do&lt;/span&gt;:&lt;/span&gt;
&lt;span id="cb14-30"&gt;&lt;a href="#cb14-30"&gt;&lt;/a&gt;            &lt;span class="cn"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;map_error(&lt;span class="cn"&gt;JSON&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;decode(json()), &lt;span class="kw"&gt;fn&lt;/span&gt; _ &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="cn"&gt;nil&lt;/span&gt; &lt;span class="kw"&gt;end&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb14-31"&gt;&lt;a href="#cb14-31"&gt;&lt;/a&gt;            &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; to(eq(&lt;span class="kw"&gt;unquote&lt;/span&gt;(&lt;span class="cn"&gt;Macro&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;escape(result))))&lt;/span&gt;
&lt;span id="cb14-32"&gt;&lt;a href="#cb14-32"&gt;&lt;/a&gt;        )&lt;/span&gt;
&lt;span id="cb14-33"&gt;&lt;a href="#cb14-33"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-34"&gt;&lt;a href="#cb14-34"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;end&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb14-35"&gt;&lt;a href="#cb14-35"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-36"&gt;&lt;a href="#cb14-36"&gt;&lt;/a&gt;&lt;span class="kw"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;unquote&lt;/code&gt; やらモジュールの順序周りやら結構苦労した． なお，いくつかテストの通らない JSONTestSuite のケースがあるので，そう言うのはとりあえずコメントアウトしてる．&lt;/p&gt;
&lt;h2 id="おしまい"&gt;おしまい&lt;/h2&gt;
&lt;p&gt;意外と綺麗にかけて満足． なお，パフォーマンスは無視してる笑．&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2019/12/21/212423</id><title type="text">OpenShift.run 2019 で Kubernetes のスケジューリングについて話してきました</title><updated>2019-12-21T21:24:23+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2019/12/21/212423"/><summary type="html">先日行われた OpenShift コミュニティのイベント OpenShift.run 2019 にて、Kubernetes Scheduler とその関連ツールについて講演してきました。公募 CFP 枠です。 OpenShift のイベントでありながら、OpenShift についてはまったく触れずひたすら Kubernetes の内部実装を解説する異色の登壇でした。実際、40 分枠の講演の中で（RedHat 社以外も含め）ベンダニュートラルな立場で登壇したのは自分だけだったようです。これは私見ですが、逆に言えばそういう内容でも CFP 採択されているというのは、運営側も「単なるマーケティングイ…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/12/19/135125</id><title type="text">plain-old jarで JUnit5 を試す</title><updated>2019-12-19T13:51:25+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/12/19/135125"/><summary type="html">https://junit.org/junit5/docs/current/user-guide/#running-tests-console-launcher に書いてあるんだけど、分かりにく過ぎたので。 $ curl -O https://repo1.maven.org/maven2/org/junit/platform/junit-platform-console-standalone/1.5.2/junit-platform-console-standalone-1.5.2.jar $ cat SampleTest.java import static org.junit.jupite…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2019-12-10-tapl-with-elm-part3.html</id><title type="text">Elm で作る TaPL のラムダ計算（その３）</title><updated>2019-12-10T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2019-12-10-tapl-with-elm-part3.html"/><summary type="html">&lt;div class="post-content" itemprop="articleBody"&gt;
    &lt;p&gt;本記事は「&lt;a href="https://adventar.org/calendars/4212"&gt;IGGG Advent Calendar 2019&lt;/a&gt;」の10日目の記事です．&lt;/p&gt;
&lt;h1 id="section"&gt;&lt;/h1&gt;
&lt;p&gt;表題の通り，TaPL という書籍で紹介されているプログラミング言語の実装例を Elm でやってみたという話です（その３）． &lt;a href="https://matsubara0507.github.io/posts/2019-12-06-tapl-with-elm-part1.html"&gt;その１&lt;/a&gt;と&lt;a href="https://matsubara0507.github.io/posts/2019-12-07-tapl-with-elm-part2.html"&gt;その２&lt;/a&gt;はこちら．&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第4章 算術式のML実装&lt;/li&gt;
&lt;li&gt;第7章 ラムダ計算の ML 実装&lt;/li&gt;
&lt;li&gt;第10章 単純型のML実装 (本記事はココ)
&lt;ul&gt;
&lt;li&gt;7章のを型付きラムダ計算にする&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;第17章 部分型付けの ML 実装&lt;/li&gt;
&lt;li&gt;第25章 System F の ML 実装
&lt;ul&gt;
&lt;li&gt;最後に型の多相性を追加&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;実装は全て下記のリポジトリにあげています:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/matsubara0507/ELaMbda"&gt;matsubara0507/ELaMbda - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;また，今まで同様に&lt;a href="https://matsubara0507.github.io/ELaMbda/?chap=chap10"&gt;Web ブラウザから遊べるようになってます&lt;/a&gt;．&lt;/p&gt;
&lt;p&gt;&lt;a href="https://matsubara0507.github.io/ELaMbda/?chap=chap10&amp;amp;exp=(\x%20:%20Bool%20.%20if%20x%20then%20x%20else%20(\f%20:%20Bool%20-%3E%20Bool%20-%3E%20Bool%20.%20f%20x%20x)%20(\x%20:%20Bool%20.%20\y%20:%20Bool%20.%20y))%20(if%20true%20then%20false%20else%20true)"&gt;&lt;img src="/assets/tapl-with-elm/chap10.jpg"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="第10章-単純型の-ml-実装"&gt;第10章 単純型の ML 実装&lt;/h2&gt;
&lt;p&gt;さて，いよいよみんな大好き「型」の登場だ． 10章は少し面白くて，4章で実装した算術式の真偽値に関する部分と7章の型なしラムダ計算を組み合わせて，更にそれに型をのせるプログラミング言語を実装する． つまり，今までの実装をちゃんとやっていれば割とサクッとできています．&lt;/p&gt;
&lt;h1 id="section-1"&gt;&lt;/h1&gt;
&lt;p&gt;なお，同期各位は全然やらなかったせいか10章を5週ぐらいやっている笑．&lt;/p&gt;
&lt;h3 id="構文規則"&gt;構文規則&lt;/h3&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode txt"&gt;&lt;code class="sourceCode default"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1"&gt;&lt;/a&gt;t := x       [変数]&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2"&gt;&lt;/a&gt;   | \x:T.t  [ラムダ抽象]&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3"&gt;&lt;/a&gt;   | t t     [関数適用]&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4"&gt;&lt;/a&gt;   | true&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5"&gt;&lt;/a&gt;   | false&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6"&gt;&lt;/a&gt;   | if t then t else t&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8"&gt;&lt;/a&gt;v := \x:T.t&lt;/span&gt;
&lt;span id="cb1-9"&gt;&lt;a href="#cb1-9"&gt;&lt;/a&gt;   | true&lt;/span&gt;
&lt;span id="cb1-10"&gt;&lt;a href="#cb1-10"&gt;&lt;/a&gt;   | false&lt;/span&gt;
&lt;span id="cb1-11"&gt;&lt;a href="#cb1-11"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-12"&gt;&lt;a href="#cb1-12"&gt;&lt;/a&gt;T := Bool    [真偽値型]&lt;/span&gt;
&lt;span id="cb1-13"&gt;&lt;a href="#cb1-13"&gt;&lt;/a&gt;   | T -&amp;gt; T  [関数型]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ラムダ抽象には型注釈(&lt;code&gt;:T&lt;/code&gt; の部分)がある． なんで付けるのかとかは9章に書いてあるのでぜひ TaPL を買って読んでください(おい)． これを Elm の型として実装する:&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2"&gt;&lt;/a&gt;    &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;TmApp&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;TmTrue&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;TmFalse&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;TmIf&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="#cb2-10"&gt;&lt;/a&gt;    &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt; &lt;span class="co"&gt;-- Arrow の Arr ね&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="#cb2-11"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-12"&gt;&lt;a href="#cb2-12"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-13"&gt;&lt;a href="#cb2-13"&gt;&lt;/a&gt;&lt;span class="fu"&gt;isval&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-14"&gt;&lt;a href="#cb2-14"&gt;&lt;/a&gt;&lt;span class="fu"&gt;isval&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-15"&gt;&lt;a href="#cb2-15"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-16"&gt;&lt;a href="#cb2-16"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-17"&gt;&lt;a href="#cb2-17"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-18"&gt;&lt;a href="#cb2-18"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-19"&gt;&lt;a href="#cb2-19"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmTrue&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-20"&gt;&lt;a href="#cb2-20"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-21"&gt;&lt;a href="#cb2-21"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-22"&gt;&lt;a href="#cb2-22"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmFalse&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-23"&gt;&lt;a href="#cb2-23"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-24"&gt;&lt;a href="#cb2-24"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-25"&gt;&lt;a href="#cb2-25"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-26"&gt;&lt;a href="#cb2-26"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-27"&gt;&lt;a href="#cb2-27"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-28"&gt;&lt;a href="#cb2-28"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;List&lt;/span&gt; ( &lt;span class="dt"&gt;String&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Binding&lt;/span&gt; )&lt;/span&gt;
&lt;span id="cb2-29"&gt;&lt;a href="#cb2-29"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Binding&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;NameBind&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;型の型 &lt;code&gt;Ty&lt;/code&gt; 以外は，4章と7章の &lt;code&gt;Term&lt;/code&gt; や &lt;code&gt;isval&lt;/code&gt; を合体させているだけだ．&lt;/p&gt;
&lt;h3 id="評価規則"&gt;評価規則&lt;/h3&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode txt"&gt;&lt;code class="sourceCode default"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1"&gt;&lt;/a&gt;// 7章の評価規則&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2"&gt;&lt;/a&gt; t1 =&amp;gt; t1&amp;#39;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3"&gt;&lt;/a&gt;---------------&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4"&gt;&lt;/a&gt; t1 t2 =&amp;gt; t1&amp;#39; t2&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6"&gt;&lt;/a&gt; t2 =&amp;gt; t2&amp;#39;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7"&gt;&lt;/a&gt;---------------&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8"&gt;&lt;/a&gt; v1 t2 =&amp;gt; v1 t2&amp;#39;&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10"&gt;&lt;/a&gt; (\x:T.t12) v2 -&amp;gt; [x|-&amp;gt; v2]t12&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12"&gt;&lt;/a&gt;// 4章の評価規則&lt;/span&gt;
&lt;span id="cb3-13"&gt;&lt;a href="#cb3-13"&gt;&lt;/a&gt; if true then t2 else t3 =&amp;gt; t2&lt;/span&gt;
&lt;span id="cb3-14"&gt;&lt;a href="#cb3-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-15"&gt;&lt;a href="#cb3-15"&gt;&lt;/a&gt; if false then t2 else t3 =&amp;gt; t3&lt;/span&gt;
&lt;span id="cb3-16"&gt;&lt;a href="#cb3-16"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-17"&gt;&lt;a href="#cb3-17"&gt;&lt;/a&gt; t1 -&amp;gt; t1&amp;#39;&lt;/span&gt;
&lt;span id="cb3-18"&gt;&lt;a href="#cb3-18"&gt;&lt;/a&gt;-------------------------------------------------&lt;/span&gt;
&lt;span id="cb3-19"&gt;&lt;a href="#cb3-19"&gt;&lt;/a&gt; if t1 then t2 else t3 =&amp;gt; if t1&amp;#39; then t2 else t3&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;評価規則も同様に型注釈の構文が追加されただけでほとんど変わらない． 変わらないということはすなわち，実行時(評価)には型の有無は影響しないということだ． 構文規則同様，4章と7章の実装を組み合わせることで実装が終わる:&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;eval&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2"&gt;&lt;/a&gt;&lt;span class="fu"&gt;eval&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;if&lt;/span&gt; &lt;span class="fu"&gt;isval&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="cf"&gt;then&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-5"&gt;&lt;a href="#cb4-5"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-6"&gt;&lt;a href="#cb4-6"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;andThen&lt;/span&gt; (&lt;span class="fu"&gt;eval&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt;) (&lt;span class="fu"&gt;eval1&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb4-7"&gt;&lt;a href="#cb4-7"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-8"&gt;&lt;a href="#cb4-8"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- あらゆる TmAbs のパターンマッチに Ty のパラメーターを追加する必要はある&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-9"&gt;&lt;a href="#cb4-9"&gt;&lt;/a&gt;&lt;span class="fu"&gt;eval1&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-10"&gt;&lt;a href="#cb4-10"&gt;&lt;/a&gt;&lt;span class="fu"&gt;eval1&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-11"&gt;&lt;a href="#cb4-11"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-12"&gt;&lt;a href="#cb4-12"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmApp&lt;/span&gt; (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="fu"&gt;t12&lt;/span&gt;) &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-13"&gt;&lt;a href="#cb4-13"&gt;&lt;/a&gt;            &lt;span class="cf"&gt;if&lt;/span&gt; &lt;span class="fu"&gt;isval&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="cf"&gt;then&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-14"&gt;&lt;a href="#cb4-14"&gt;&lt;/a&gt;                &lt;span class="dt"&gt;Just&lt;/span&gt; (&lt;span class="fu"&gt;termSubstTop&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="fu"&gt;t12&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb4-15"&gt;&lt;a href="#cb4-15"&gt;&lt;/a&gt;            &lt;span class="cf"&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-16"&gt;&lt;a href="#cb4-16"&gt;&lt;/a&gt;                &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; (&lt;span class="dt"&gt;TmApp&lt;/span&gt; (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="fu"&gt;t12&lt;/span&gt;)) (&lt;span class="fu"&gt;eval1&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb4-17"&gt;&lt;a href="#cb4-17"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-18"&gt;&lt;a href="#cb4-18"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmApp&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-19"&gt;&lt;a href="#cb4-19"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; (&lt;span class="fu"&gt;flip&lt;/span&gt; &lt;span class="dt"&gt;TmApp&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt;) (&lt;span class="fu"&gt;eval1&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb4-20"&gt;&lt;a href="#cb4-20"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-21"&gt;&lt;a href="#cb4-21"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmIf&lt;/span&gt; &lt;span class="dt"&gt;TmTrue&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-22"&gt;&lt;a href="#cb4-22"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-23"&gt;&lt;a href="#cb4-23"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-24"&gt;&lt;a href="#cb4-24"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmIf&lt;/span&gt; &lt;span class="dt"&gt;TmFalse&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="fu"&gt;t3&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-25"&gt;&lt;a href="#cb4-25"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;t3&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-26"&gt;&lt;a href="#cb4-26"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-27"&gt;&lt;a href="#cb4-27"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmIf&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="fu"&gt;t3&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-28"&gt;&lt;a href="#cb4-28"&gt;&lt;/a&gt;            &lt;span class="fu"&gt;eval1&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt; &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; (\&lt;span class="fu"&gt;t1_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;TmIf&lt;/span&gt; &lt;span class="fu"&gt;t1_&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="fu"&gt;t3&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb4-29"&gt;&lt;a href="#cb4-29"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-30"&gt;&lt;a href="#cb4-30"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-31"&gt;&lt;a href="#cb4-31"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-32"&gt;&lt;a href="#cb4-32"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-33"&gt;&lt;a href="#cb4-33"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- t に s を代入する&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-34"&gt;&lt;a href="#cb4-34"&gt;&lt;/a&gt;&lt;span class="fu"&gt;termSubstTop&lt;/span&gt; : &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-35"&gt;&lt;a href="#cb4-35"&gt;&lt;/a&gt;&lt;span class="fu"&gt;termSubstTop&lt;/span&gt; &lt;span class="fu"&gt;s&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="型付け規則"&gt;型付け規則&lt;/h3&gt;
&lt;p&gt;ここからが新しい． いわゆる型検査のことだ． TaPL では「正しく型付けされた項はおかしくならない」という性質(安全性・健全性ともいう)について議論されている(8章で)． 例えば，これから定義する型検査が通った項(&lt;code&gt;Term&lt;/code&gt;)は &lt;code&gt;eval&lt;/code&gt; 関数を適用しても無限ループなどにはならない． さて，そのための型付け規則は次のようになっている:&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode txt"&gt;&lt;code class="sourceCode default"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1"&gt;&lt;/a&gt;// 真偽値の型付け規則&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2"&gt;&lt;/a&gt; true : Bool&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4"&gt;&lt;/a&gt; false : Bool&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6"&gt;&lt;/a&gt; t1 : Bool    t2 : T    t3 : T&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7"&gt;&lt;/a&gt;-------------------------------&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8"&gt;&lt;/a&gt; if t1 then t2 else t3 : T&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-10"&gt;&lt;a href="#cb5-10"&gt;&lt;/a&gt;// 単純ラムダ計算の型付け規則&lt;/span&gt;
&lt;span id="cb5-11"&gt;&lt;a href="#cb5-11"&gt;&lt;/a&gt; x : T ∈ Γ&lt;/span&gt;
&lt;span id="cb5-12"&gt;&lt;a href="#cb5-12"&gt;&lt;/a&gt;-----------&lt;/span&gt;
&lt;span id="cb5-13"&gt;&lt;a href="#cb5-13"&gt;&lt;/a&gt; Γ ⊢ x : T&lt;/span&gt;
&lt;span id="cb5-14"&gt;&lt;a href="#cb5-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-15"&gt;&lt;a href="#cb5-15"&gt;&lt;/a&gt; Γ, x : T1 ⊢ t2 : T2&lt;/span&gt;
&lt;span id="cb5-16"&gt;&lt;a href="#cb5-16"&gt;&lt;/a&gt;-----------------------------&lt;/span&gt;
&lt;span id="cb5-17"&gt;&lt;a href="#cb5-17"&gt;&lt;/a&gt; Γ ⊢ \x : T1 . t2 : T1 -&amp;gt; T2&lt;/span&gt;
&lt;span id="cb5-18"&gt;&lt;a href="#cb5-18"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-19"&gt;&lt;a href="#cb5-19"&gt;&lt;/a&gt; Γ ⊢ t1 : T11 -&amp;gt; T12    Γ ⊢ t2 : T11&lt;/span&gt;
&lt;span id="cb5-20"&gt;&lt;a href="#cb5-20"&gt;&lt;/a&gt;-------------------------------------&lt;/span&gt;
&lt;span id="cb5-21"&gt;&lt;a href="#cb5-21"&gt;&lt;/a&gt; Γ ⊢ t1 t2 : T12&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ここで新しく出てくる &lt;code&gt;Γ&lt;/code&gt; は型環境と言い，変数と型の対応関係を線形リストのような感じに保持している． &lt;code&gt;Γ ⊢ t : T&lt;/code&gt; というのは「型環境 &lt;code&gt;Γ&lt;/code&gt; のもと項 &lt;code&gt;t&lt;/code&gt; は型 &lt;code&gt;T&lt;/code&gt; に型付け可能」という風に読める(たぶん)． まぁ実装してみればわかる(ほんとか？):&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- 型環境には Context を再利用する&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;List&lt;/span&gt; ( &lt;span class="dt"&gt;String&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Binding&lt;/span&gt; )&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Binding&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4"&gt;&lt;/a&gt;    &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;NameBind&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;VarBind&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt; &lt;span class="co"&gt;-- 変数の型を保持&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-6"&gt;&lt;a href="#cb6-6"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-7"&gt;&lt;a href="#cb6-7"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- 項 t の型が最終的に導出できれば型付け可能ということになる&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-8"&gt;&lt;a href="#cb6-8"&gt;&lt;/a&gt;&lt;span class="fu"&gt;typeof&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-9"&gt;&lt;a href="#cb6-9"&gt;&lt;/a&gt;&lt;span class="fu"&gt;typeof&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-10"&gt;&lt;a href="#cb6-10"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-11"&gt;&lt;a href="#cb6-11"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-12"&gt;&lt;a href="#cb6-12"&gt;&lt;/a&gt;            &lt;span class="co"&gt;-- Context から型情報を引っ張ってくる&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-13"&gt;&lt;a href="#cb6-13"&gt;&lt;/a&gt;            &lt;span class="fu"&gt;getTypeFromContext&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-14"&gt;&lt;a href="#cb6-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-15"&gt;&lt;a href="#cb6-15"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt; &lt;span class="fu"&gt;ty1&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-16"&gt;&lt;a href="#cb6-16"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-17"&gt;&lt;a href="#cb6-17"&gt;&lt;/a&gt;                &lt;span class="co"&gt;-- Context に 変数と型の対応を追加する&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-18"&gt;&lt;a href="#cb6-18"&gt;&lt;/a&gt;                &lt;span class="fu"&gt;ctx1&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;addbinding&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt; (&lt;span class="dt"&gt;VarBind&lt;/span&gt; &lt;span class="fu"&gt;ty1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb6-19"&gt;&lt;a href="#cb6-19"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-20"&gt;&lt;a href="#cb6-20"&gt;&lt;/a&gt;            &lt;span class="co"&gt;-- ラムダ抽象は中の項 t2 が型付け可能である必要がある&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-21"&gt;&lt;a href="#cb6-21"&gt;&lt;/a&gt;            &lt;span class="fu"&gt;typeof&lt;/span&gt; &lt;span class="fu"&gt;ctx1&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-22"&gt;&lt;a href="#cb6-22"&gt;&lt;/a&gt;                &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; (\&lt;span class="fu"&gt;ty2&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="fu"&gt;ty1&lt;/span&gt; &lt;span class="fu"&gt;ty2&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb6-23"&gt;&lt;a href="#cb6-23"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-24"&gt;&lt;a href="#cb6-24"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmApp&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-25"&gt;&lt;a href="#cb6-25"&gt;&lt;/a&gt;            &lt;span class="cf"&gt;case&lt;/span&gt; ( &lt;span class="fu"&gt;typeof&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;typeof&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; ) &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-26"&gt;&lt;a href="#cb6-26"&gt;&lt;/a&gt;                ( &lt;span class="dt"&gt;Just&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="fu"&gt;ty11&lt;/span&gt; &lt;span class="fu"&gt;ty12&lt;/span&gt;)&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;ty2&lt;/span&gt; ) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-27"&gt;&lt;a href="#cb6-27"&gt;&lt;/a&gt;                    &lt;span class="co"&gt;-- 関数適用の場合は引数の型 ty11 と適用する項の型 ty2 が同じである必要がある&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-28"&gt;&lt;a href="#cb6-28"&gt;&lt;/a&gt;                    &lt;span class="cf"&gt;if&lt;/span&gt; &lt;span class="fu"&gt;ty11&lt;/span&gt; &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="fu"&gt;ty2&lt;/span&gt; &lt;span class="cf"&gt;then&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-29"&gt;&lt;a href="#cb6-29"&gt;&lt;/a&gt;                        &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;ty12&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-30"&gt;&lt;a href="#cb6-30"&gt;&lt;/a&gt;                    &lt;span class="cf"&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-31"&gt;&lt;a href="#cb6-31"&gt;&lt;/a&gt;                        &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-32"&gt;&lt;a href="#cb6-32"&gt;&lt;/a&gt;                &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-33"&gt;&lt;a href="#cb6-33"&gt;&lt;/a&gt;                    &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-34"&gt;&lt;a href="#cb6-34"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-35"&gt;&lt;a href="#cb6-35"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmTrue&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-36"&gt;&lt;a href="#cb6-36"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-37"&gt;&lt;a href="#cb6-37"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-38"&gt;&lt;a href="#cb6-38"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmFalse&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-39"&gt;&lt;a href="#cb6-39"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-40"&gt;&lt;a href="#cb6-40"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-41"&gt;&lt;a href="#cb6-41"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmIf&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt; &lt;span class="fu"&gt;t3&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-42"&gt;&lt;a href="#cb6-42"&gt;&lt;/a&gt;            &lt;span class="cf"&gt;case&lt;/span&gt; ( &lt;span class="fu"&gt;typeof&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;typeof&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t2&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;typeof&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t3&lt;/span&gt; ) &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-43"&gt;&lt;a href="#cb6-43"&gt;&lt;/a&gt;                ( &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;ty2&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;ty3&lt;/span&gt; ) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-44"&gt;&lt;a href="#cb6-44"&gt;&lt;/a&gt;                    &lt;span class="co"&gt;-- if-then-else の場合は t2 と t3 の型が同じである必要がある&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-45"&gt;&lt;a href="#cb6-45"&gt;&lt;/a&gt;                    &lt;span class="cf"&gt;if&lt;/span&gt; &lt;span class="fu"&gt;ty2&lt;/span&gt; &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="fu"&gt;ty3&lt;/span&gt; &lt;span class="cf"&gt;then&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-46"&gt;&lt;a href="#cb6-46"&gt;&lt;/a&gt;                        &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;ty2&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-47"&gt;&lt;a href="#cb6-47"&gt;&lt;/a&gt;                    &lt;span class="cf"&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-48"&gt;&lt;a href="#cb6-48"&gt;&lt;/a&gt;                        &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-49"&gt;&lt;a href="#cb6-49"&gt;&lt;/a&gt;                &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-50"&gt;&lt;a href="#cb6-50"&gt;&lt;/a&gt;                    &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-51"&gt;&lt;a href="#cb6-51"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-52"&gt;&lt;a href="#cb6-52"&gt;&lt;/a&gt;&lt;span class="fu"&gt;getTypeFromContext&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-53"&gt;&lt;a href="#cb6-53"&gt;&lt;/a&gt;&lt;span class="fu"&gt;getTypeFromContext&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;idx&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-54"&gt;&lt;a href="#cb6-54"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;getbinding&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;idx&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-55"&gt;&lt;a href="#cb6-55"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Just&lt;/span&gt; (&lt;span class="dt"&gt;VarBind&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt;) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-56"&gt;&lt;a href="#cb6-56"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-57"&gt;&lt;a href="#cb6-57"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-58"&gt;&lt;a href="#cb6-58"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-59"&gt;&lt;a href="#cb6-59"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-60"&gt;&lt;a href="#cb6-60"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-61"&gt;&lt;a href="#cb6-61"&gt;&lt;/a&gt;&lt;span class="fu"&gt;getbinding&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Binding&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-62"&gt;&lt;a href="#cb6-62"&gt;&lt;/a&gt;&lt;span class="fu"&gt;getbinding&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;n&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-63"&gt;&lt;a href="#cb6-63"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; ( &lt;span class="fu"&gt;ctx&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;n&lt;/span&gt; ) &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-64"&gt;&lt;a href="#cb6-64"&gt;&lt;/a&gt;        ( []&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; ) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-65"&gt;&lt;a href="#cb6-65"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-66"&gt;&lt;a href="#cb6-66"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-67"&gt;&lt;a href="#cb6-67"&gt;&lt;/a&gt;        ( ( &lt;span class="fu"&gt;_&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;bind&lt;/span&gt; ) &lt;span class="op"&gt;::&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; ) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-68"&gt;&lt;a href="#cb6-68"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="fu"&gt;bind&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-69"&gt;&lt;a href="#cb6-69"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-70"&gt;&lt;a href="#cb6-70"&gt;&lt;/a&gt;        ( &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;::&lt;/span&gt; &lt;span class="fu"&gt;next&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;_&lt;/span&gt; ) &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-71"&gt;&lt;a href="#cb6-71"&gt;&lt;/a&gt;            &lt;span class="fu"&gt;getbinding&lt;/span&gt; &lt;span class="fu"&gt;next&lt;/span&gt; (&lt;span class="fu"&gt;n&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb6-72"&gt;&lt;a href="#cb6-72"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-73"&gt;&lt;a href="#cb6-73"&gt;&lt;/a&gt;&lt;span class="fu"&gt;addbinding&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Binding&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Context&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-74"&gt;&lt;a href="#cb6-74"&gt;&lt;/a&gt;&lt;span class="fu"&gt;addbinding&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt; &lt;span class="fu"&gt;bind&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-75"&gt;&lt;a href="#cb6-75"&gt;&lt;/a&gt;    ( &lt;span class="fu"&gt;x&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;bind&lt;/span&gt; ) &lt;span class="op"&gt;::&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;REPL で試してみる:&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;TaPL&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Chap10&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="dt"&gt;Term&lt;/span&gt;(&lt;span class="op"&gt;..&lt;/span&gt;)&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt;(&lt;span class="op"&gt;..&lt;/span&gt;)&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Binding&lt;/span&gt;(&lt;span class="op"&gt;..&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- (\x : (Bool -&amp;gt; Bool) . (\f : (Bool -&amp;gt; Bool -&amp;gt; Bool) . f x)) (\x : Bool . x)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3"&gt;&lt;/a&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;typeof&lt;/span&gt; [] (&lt;span class="dt"&gt;TmApp&lt;/span&gt; (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;) (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;f&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;) &lt;span class="dt"&gt;TyBool&lt;/span&gt;) (&lt;span class="dt"&gt;TmApp&lt;/span&gt; (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;) (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;)))) (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt; (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;)))&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4"&gt;&lt;/a&gt;&lt;span class="dt"&gt;Just&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;) &lt;span class="dt"&gt;TyBool&lt;/span&gt;) &lt;span class="dt"&gt;TyBool&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5"&gt;&lt;/a&gt;    : &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- (\x . x x) (\x . x x) はうまく型付けできない&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="#cb7-7"&gt;&lt;/a&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;typeof&lt;/span&gt; [] (&lt;span class="dt"&gt;TmApp&lt;/span&gt; (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;) (&lt;span class="dt"&gt;TmApp&lt;/span&gt; (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;) (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;))) (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;) (&lt;span class="dt"&gt;TmApp&lt;/span&gt; (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;) (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;))))&lt;/span&gt;
&lt;span id="cb7-8"&gt;&lt;a href="#cb7-8"&gt;&lt;/a&gt;&lt;span class="dt"&gt;Nothing&lt;/span&gt; : &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="文字列に変換"&gt;文字列に変換&lt;/h3&gt;
&lt;p&gt;基本的に4・7章の定義を利用すれば良いのだが，型注釈ができるようになったので型も変換できるようにする:&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;display&lt;/span&gt; : &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2"&gt;&lt;/a&gt;&lt;span class="fu"&gt;display&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;printtm&lt;/span&gt; [] &lt;span class="fu"&gt;t&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; (&lt;span class="fu"&gt;dropIfStartsWith&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;(&amp;quot;&lt;/span&gt;) &lt;span class="co"&gt;-- 最初と最後のカッコを消している&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; (&lt;span class="fu"&gt;dropIfEndsWith&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-6"&gt;&lt;a href="#cb8-6"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;withDefault&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-7"&gt;&lt;a href="#cb8-7"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-8"&gt;&lt;a href="#cb8-8"&gt;&lt;/a&gt;&lt;span class="fu"&gt;printtm&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-9"&gt;&lt;a href="#cb8-9"&gt;&lt;/a&gt;&lt;span class="fu"&gt;printtm&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-10"&gt;&lt;a href="#cb8-10"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-11"&gt;&lt;a href="#cb8-11"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-12"&gt;&lt;a href="#cb8-12"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;let&lt;/span&gt; &lt;span class="co"&gt;-- 重複しない変数名を生成して Context に積む&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-13"&gt;&lt;a href="#cb8-13"&gt;&lt;/a&gt;                ( &lt;span class="fu"&gt;ctx1&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;x1&lt;/span&gt; ) &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;pickfreshname&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-14"&gt;&lt;a href="#cb8-14"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-15"&gt;&lt;a href="#cb8-15"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-16"&gt;&lt;a href="#cb8-16"&gt;&lt;/a&gt;                (\&lt;span class="fu"&gt;s1&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;concat&lt;/span&gt; [ &lt;span class="st"&gt;&amp;quot;(\\&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;x1&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; : &amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;printty&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;. &amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;s1&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;)&amp;quot;&lt;/span&gt; ])&lt;/span&gt;
&lt;span id="cb8-17"&gt;&lt;a href="#cb8-17"&gt;&lt;/a&gt;                (&lt;span class="fu"&gt;printtm&lt;/span&gt; &lt;span class="fu"&gt;ctx1&lt;/span&gt; &lt;span class="fu"&gt;t1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-18"&gt;&lt;a href="#cb8-18"&gt;&lt;/a&gt;        &lt;span class="op"&gt;...&lt;/span&gt; &lt;span class="co"&gt;-- あとは同じ&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-19"&gt;&lt;a href="#cb8-19"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-20"&gt;&lt;a href="#cb8-20"&gt;&lt;/a&gt;&lt;span class="fu"&gt;printty&lt;/span&gt; : &lt;span class="dt"&gt;Ty&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-21"&gt;&lt;a href="#cb8-21"&gt;&lt;/a&gt;&lt;span class="fu"&gt;printty&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-22"&gt;&lt;a href="#cb8-22"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-23"&gt;&lt;a href="#cb8-23"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="fu"&gt;ty1&lt;/span&gt; &lt;span class="fu"&gt;ty2&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-24"&gt;&lt;a href="#cb8-24"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;String&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;concat&lt;/span&gt; [ &lt;span class="st"&gt;&amp;quot;(&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;printty&lt;/span&gt; &lt;span class="fu"&gt;ty1&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; -&amp;gt; &amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;printty&lt;/span&gt; &lt;span class="fu"&gt;ty2&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;)&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id="cb8-25"&gt;&lt;a href="#cb8-25"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-26"&gt;&lt;a href="#cb8-26"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;TyBool&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-27"&gt;&lt;a href="#cb8-27"&gt;&lt;/a&gt;            &lt;span class="st"&gt;&amp;quot;Bool&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-28"&gt;&lt;a href="#cb8-28"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-29"&gt;&lt;a href="#cb8-29"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- Context から重複する変数名を探し &amp;#39; を追加する&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-30"&gt;&lt;a href="#cb8-30"&gt;&lt;/a&gt;&lt;span class="fu"&gt;pickfreshname&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; ( &lt;span class="dt"&gt;Context&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; )&lt;/span&gt;
&lt;span id="cb8-31"&gt;&lt;a href="#cb8-31"&gt;&lt;/a&gt;&lt;span class="fu"&gt;pickfreshname&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;x&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;REPL で試す:&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;display&lt;/span&gt; (&lt;span class="dt"&gt;TmApp&lt;/span&gt; (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;) (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;f&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;) &lt;span class="dt"&gt;TyBool&lt;/span&gt;) (&lt;span class="dt"&gt;TmApp&lt;/span&gt; (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;) (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;)))) (&lt;span class="dt"&gt;TmAbs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt; (&lt;span class="dt"&gt;TmVar&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;)))&lt;/span&gt;
&lt;span id="cb9-2"&gt;&lt;a href="#cb9-2"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;quot;(\\x : (Bool -&amp;gt; Bool). (\\f : ((Bool -&amp;gt; Bool) -&amp;gt; Bool). (f x))) (\\x : Bool. x)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-3"&gt;&lt;a href="#cb9-3"&gt;&lt;/a&gt;    : &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="パーサー"&gt;パーサー&lt;/h3&gt;
&lt;p&gt;これも同様に4・7章の実装を合わせるだけ:&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;TaPL&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Parser&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="fu"&gt;parse&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="#cb10-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; ((&lt;span class="op"&gt;|.&lt;/span&gt;)&lt;span class="op"&gt;,&lt;/span&gt; (&lt;span class="op"&gt;|=&lt;/span&gt;)&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="#cb10-4"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;TaPL&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Chap10&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="dt"&gt;Term&lt;/span&gt;(&lt;span class="op"&gt;..&lt;/span&gt;)&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt;(&lt;span class="op"&gt;..&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="#cb10-5"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="#cb10-6"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="#cb10-7"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;env&lt;/span&gt; : &lt;span class="dt"&gt;Dict&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-8"&gt;&lt;a href="#cb10-8"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;depth&lt;/span&gt; : &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-9"&gt;&lt;a href="#cb10-9"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb10-10"&gt;&lt;a href="#cb10-10"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-11"&gt;&lt;a href="#cb10-11"&gt;&lt;/a&gt;&lt;span class="fu"&gt;iniCtx&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-12"&gt;&lt;a href="#cb10-12"&gt;&lt;/a&gt;&lt;span class="fu"&gt;iniCtx&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-13"&gt;&lt;a href="#cb10-13"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;env&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Dict&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;empty&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;depth&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; }&lt;/span&gt;
&lt;span id="cb10-14"&gt;&lt;a href="#cb10-14"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-15"&gt;&lt;a href="#cb10-15"&gt;&lt;/a&gt;&lt;span class="fu"&gt;parse&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Result&lt;/span&gt; (&lt;span class="dt"&gt;List&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;DeadEnd&lt;/span&gt;) &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-16"&gt;&lt;a href="#cb10-16"&gt;&lt;/a&gt;&lt;span class="fu"&gt;parse&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-17"&gt;&lt;a href="#cb10-17"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;run&lt;/span&gt; &lt;span class="fu"&gt;parser&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-18"&gt;&lt;a href="#cb10-18"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-19"&gt;&lt;a href="#cb10-19"&gt;&lt;/a&gt;&lt;span class="fu"&gt;parser&lt;/span&gt; : &lt;span class="dt"&gt;Parser&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-20"&gt;&lt;a href="#cb10-20"&gt;&lt;/a&gt;&lt;span class="fu"&gt;parser&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-21"&gt;&lt;a href="#cb10-21"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;termParser&lt;/span&gt; &lt;span class="fu"&gt;iniCtx&lt;/span&gt; &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-22"&gt;&lt;a href="#cb10-22"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-23"&gt;&lt;a href="#cb10-23"&gt;&lt;/a&gt;&lt;span class="fu"&gt;termParser&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-24"&gt;&lt;a href="#cb10-24"&gt;&lt;/a&gt;&lt;span class="fu"&gt;termParser&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-25"&gt;&lt;a href="#cb10-25"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;oneOf&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-26"&gt;&lt;a href="#cb10-26"&gt;&lt;/a&gt;        [ &lt;span class="fu"&gt;parParser&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="co"&gt;-- 括弧のパーサー&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-27"&gt;&lt;a href="#cb10-27"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;absParser&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="co"&gt;-- ラムダ抽象のパーサー&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-28"&gt;&lt;a href="#cb10-28"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;valParser&lt;/span&gt;     &lt;span class="co"&gt;-- ture/false のパーサー&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-29"&gt;&lt;a href="#cb10-29"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;ifParser&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt;  &lt;span class="co"&gt;-- if-then-else のパーサー&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-30"&gt;&lt;a href="#cb10-30"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;varParser&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="co"&gt;-- 変数のパーサー&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-31"&gt;&lt;a href="#cb10-31"&gt;&lt;/a&gt;        ] &lt;span class="co"&gt;-- 関数適用のパーサーだけ分けてるのは左再帰対策(その２参照)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-32"&gt;&lt;a href="#cb10-32"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;andThen&lt;/span&gt; (&lt;span class="fu"&gt;appParser&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;言わずもがな，型注釈のパースをする必要があるので，&lt;code&gt;absParser&lt;/code&gt; はその２のと若干異なる:&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;absParser&lt;/span&gt; : &lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt; &lt;span class="dt"&gt;Term&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2"&gt;&lt;/a&gt;&lt;span class="fu"&gt;absParser&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-3"&gt;&lt;a href="#cb11-3"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;succeed&lt;/span&gt; &lt;span class="dt"&gt;Tuple&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;pair&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-4"&gt;&lt;a href="#cb11-4"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;symbol&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\\&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-5"&gt;&lt;a href="#cb11-5"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;spaces&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-6"&gt;&lt;a href="#cb11-6"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|=&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;lazy&lt;/span&gt; (\&lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;varStrParser&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb11-7"&gt;&lt;a href="#cb11-7"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;spaces&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-8"&gt;&lt;a href="#cb11-8"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;symbol&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;:&amp;quot;&lt;/span&gt;            &lt;span class="co"&gt;-- ここから&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-9"&gt;&lt;a href="#cb11-9"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;spaces&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-10"&gt;&lt;a href="#cb11-10"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|=&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;lazy&lt;/span&gt; (\&lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;tyParser&lt;/span&gt;) &lt;span class="co"&gt;-- ここまでが追加&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-11"&gt;&lt;a href="#cb11-11"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;spaces&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-12"&gt;&lt;a href="#cb11-12"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;symbol&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-13"&gt;&lt;a href="#cb11-13"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;spaces&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-14"&gt;&lt;a href="#cb11-14"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;andThen&lt;/span&gt; (&lt;span class="fu"&gt;absParserN&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb11-15"&gt;&lt;a href="#cb11-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-16"&gt;&lt;a href="#cb11-16"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- 型のパーサー&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-17"&gt;&lt;a href="#cb11-17"&gt;&lt;/a&gt;&lt;span class="fu"&gt;tyParser&lt;/span&gt; : &lt;span class="dt"&gt;Parser&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-18"&gt;&lt;a href="#cb11-18"&gt;&lt;/a&gt;&lt;span class="fu"&gt;tyParser&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-19"&gt;&lt;a href="#cb11-19"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;oneOf&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-20"&gt;&lt;a href="#cb11-20"&gt;&lt;/a&gt;        [ &lt;span class="fu"&gt;value&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Bool&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;TyBool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-21"&gt;&lt;a href="#cb11-21"&gt;&lt;/a&gt;        ]&lt;/span&gt;
&lt;span id="cb11-22"&gt;&lt;a href="#cb11-22"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;spaces&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-23"&gt;&lt;a href="#cb11-23"&gt;&lt;/a&gt;        &lt;span class="co"&gt;-- これも左再帰対策(その２参照)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-24"&gt;&lt;a href="#cb11-24"&gt;&lt;/a&gt;        &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;andThen&lt;/span&gt; &lt;span class="fu"&gt;tyArrParser&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-25"&gt;&lt;a href="#cb11-25"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-26"&gt;&lt;a href="#cb11-26"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- 関数型のパーサー&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-27"&gt;&lt;a href="#cb11-27"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- 関数型 T-&amp;gt;T は右結合(T-&amp;gt;T-&amp;gt;T は T-&amp;gt;(T-&amp;gt;T) となる)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-28"&gt;&lt;a href="#cb11-28"&gt;&lt;/a&gt;&lt;span class="fu"&gt;tyArrParser&lt;/span&gt; : &lt;span class="dt"&gt;Ty&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt; &lt;span class="dt"&gt;Ty&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-29"&gt;&lt;a href="#cb11-29"&gt;&lt;/a&gt;&lt;span class="fu"&gt;tyArrParser&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-30"&gt;&lt;a href="#cb11-30"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;oneOf&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-31"&gt;&lt;a href="#cb11-31"&gt;&lt;/a&gt;        [ &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;succeed&lt;/span&gt; (&lt;span class="dt"&gt;TyArr&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb11-32"&gt;&lt;a href="#cb11-32"&gt;&lt;/a&gt;            &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;keyword&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;-&amp;gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-33"&gt;&lt;a href="#cb11-33"&gt;&lt;/a&gt;            &lt;span class="op"&gt;|.&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;spaces&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-34"&gt;&lt;a href="#cb11-34"&gt;&lt;/a&gt;            &lt;span class="op"&gt;|=&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;lazy&lt;/span&gt; (\&lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;tyParser&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb11-35"&gt;&lt;a href="#cb11-35"&gt;&lt;/a&gt;        &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;succeed&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-36"&gt;&lt;a href="#cb11-36"&gt;&lt;/a&gt;        ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;REPL で試してみる:&lt;/p&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb12-1"&gt;&lt;a href="#cb12-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt;  &lt;span class="st"&gt;&amp;quot;(\\x : Bool . if x then x else (\\f : Bool -&amp;gt; Bool -&amp;gt; Bool . f x x) (\\x : Bool . \\y : Bool . y)) (if true then false else true)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="#cb12-2"&gt;&lt;/a&gt;&lt;span class="op"&gt;|&lt;/span&gt;   &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;parse&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="#cb12-3"&gt;&lt;/a&gt;&lt;span class="op"&gt;|&lt;/span&gt;   &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;toMaybe&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-4"&gt;&lt;a href="#cb12-4"&gt;&lt;/a&gt;&lt;span class="op"&gt;|&lt;/span&gt;   &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;andThen&lt;/span&gt; (\&lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;typeof&lt;/span&gt; [] &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; (&lt;span class="fu"&gt;always&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt;)) &lt;span class="co"&gt;-- 型検査&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-5"&gt;&lt;a href="#cb12-5"&gt;&lt;/a&gt;&lt;span class="op"&gt;|&lt;/span&gt;   &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;andThen&lt;/span&gt; (&lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;eval&lt;/span&gt; [])&lt;/span&gt;
&lt;span id="cb12-6"&gt;&lt;a href="#cb12-6"&gt;&lt;/a&gt;&lt;span class="op"&gt;|&lt;/span&gt;   &lt;span class="op"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;map&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;display&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-7"&gt;&lt;a href="#cb12-7"&gt;&lt;/a&gt;&lt;span class="op"&gt;|&lt;/span&gt;   &lt;/span&gt;
&lt;span id="cb12-8"&gt;&lt;a href="#cb12-8"&gt;&lt;/a&gt;&lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;false&amp;quot;&lt;/span&gt; : &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;完璧だ．&lt;/p&gt;
&lt;h2 id="おまけ-spa"&gt;おまけ: SPA&lt;/h2&gt;
&lt;p&gt;前回整理したので基本的に足していくだけだ． ただし，型検査を &lt;code&gt;Calculus&lt;/code&gt; に加える必要がある:&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb13-1"&gt;&lt;a href="#cb13-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;TaPL&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="op"&gt;..&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="#cb13-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-3"&gt;&lt;a href="#cb13-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;alias&lt;/span&gt; &lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-4"&gt;&lt;a href="#cb13-4"&gt;&lt;/a&gt;    { &lt;span class="fu"&gt;parse&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Result&lt;/span&gt; (&lt;span class="dt"&gt;List&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;DeadEnd&lt;/span&gt;) &lt;span class="fu"&gt;t&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-5"&gt;&lt;a href="#cb13-5"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;typeof&lt;/span&gt; : &lt;span class="dt"&gt;Maybe&lt;/span&gt; (&lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt;) &lt;span class="co"&gt;-- 追加&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-6"&gt;&lt;a href="#cb13-6"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;eval1&lt;/span&gt; : &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-7"&gt;&lt;a href="#cb13-7"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;display&lt;/span&gt; : &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-8"&gt;&lt;a href="#cb13-8"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;init&lt;/span&gt; : &lt;span class="fu"&gt;ctx&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-9"&gt;&lt;a href="#cb13-9"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;logs&lt;/span&gt; : &lt;span class="dt"&gt;List&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-10"&gt;&lt;a href="#cb13-10"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb13-11"&gt;&lt;a href="#cb13-11"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-12"&gt;&lt;a href="#cb13-12"&gt;&lt;/a&gt;&lt;span class="fu"&gt;eval1&lt;/span&gt; : &lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; (&lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb13-13"&gt;&lt;a href="#cb13-13"&gt;&lt;/a&gt;&lt;span class="fu"&gt;typecheck&lt;/span&gt; : &lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-14"&gt;&lt;a href="#cb13-14"&gt;&lt;/a&gt;&lt;span class="fu"&gt;parse&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Result&lt;/span&gt; (&lt;span class="dt"&gt;List&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;DeadEnd&lt;/span&gt;) (&lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb13-15"&gt;&lt;a href="#cb13-15"&gt;&lt;/a&gt;&lt;span class="fu"&gt;display&lt;/span&gt; : &lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="fu"&gt;ctx&lt;/span&gt; &lt;span class="fu"&gt;t&lt;/span&gt; &lt;span class="fu"&gt;ty&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;List&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;あとは &lt;code&gt;chap10&lt;/code&gt; の定義も追加するだけ:&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode elm"&gt;&lt;code class="sourceCode elm"&gt;&lt;span id="cb14-1"&gt;&lt;a href="#cb14-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;module&lt;/span&gt; &lt;span class="dt"&gt;TaPL&lt;/span&gt; &lt;span class="kw"&gt;exposing&lt;/span&gt; (&lt;span class="op"&gt;..&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="#cb14-2"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="#cb14-3"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Chapter&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-4"&gt;&lt;a href="#cb14-4"&gt;&lt;/a&gt;    &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Chap0&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-5"&gt;&lt;a href="#cb14-5"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Chap4&lt;/span&gt; (&lt;span class="dt"&gt;Calculus&lt;/span&gt; () &lt;span class="dt"&gt;Chap4&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="dt"&gt;Never&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb14-6"&gt;&lt;a href="#cb14-6"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Chap7&lt;/span&gt; (&lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="dt"&gt;Chap7&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="dt"&gt;Chap7&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="dt"&gt;Never&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb14-7"&gt;&lt;a href="#cb14-7"&gt;&lt;/a&gt;    &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt; (&lt;span class="dt"&gt;Calculus&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Context&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Term&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;Ty&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb14-8"&gt;&lt;a href="#cb14-8"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-9"&gt;&lt;a href="#cb14-9"&gt;&lt;/a&gt;&lt;span class="fu"&gt;init&lt;/span&gt; : &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Chapter&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-10"&gt;&lt;a href="#cb14-10"&gt;&lt;/a&gt;&lt;span class="fu"&gt;init&lt;/span&gt; &lt;span class="fu"&gt;s&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-11"&gt;&lt;a href="#cb14-11"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;s&lt;/span&gt; &lt;span class="cf"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-12"&gt;&lt;a href="#cb14-12"&gt;&lt;/a&gt;        &lt;span class="st"&gt;&amp;quot;chap4&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-13"&gt;&lt;a href="#cb14-13"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-14"&gt;&lt;a href="#cb14-14"&gt;&lt;/a&gt;        &lt;span class="st"&gt;&amp;quot;chap7&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-15"&gt;&lt;a href="#cb14-15"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-16"&gt;&lt;a href="#cb14-16"&gt;&lt;/a&gt;        &lt;span class="co"&gt;-- 追加&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-17"&gt;&lt;a href="#cb14-17"&gt;&lt;/a&gt;        &lt;span class="st"&gt;&amp;quot;chap10&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-18"&gt;&lt;a href="#cb14-18"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-19"&gt;&lt;a href="#cb14-19"&gt;&lt;/a&gt;                { &lt;span class="fu"&gt;eval1&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;eval1&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-20"&gt;&lt;a href="#cb14-20"&gt;&lt;/a&gt;                &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;display&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;display&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-21"&gt;&lt;a href="#cb14-21"&gt;&lt;/a&gt;                &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;parse&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;parse&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-22"&gt;&lt;a href="#cb14-22"&gt;&lt;/a&gt;                &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;init&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; []&lt;/span&gt;
&lt;span id="cb14-23"&gt;&lt;a href="#cb14-23"&gt;&lt;/a&gt;                &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;logs&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; []&lt;/span&gt;
&lt;span id="cb14-24"&gt;&lt;a href="#cb14-24"&gt;&lt;/a&gt;                &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;syntax&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;syntax&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-25"&gt;&lt;a href="#cb14-25"&gt;&lt;/a&gt;                &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="fu"&gt;typeof&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; &lt;span class="dt"&gt;Chap10&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;typeof&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-26"&gt;&lt;a href="#cb14-26"&gt;&lt;/a&gt;                }&lt;/span&gt;
&lt;span id="cb14-27"&gt;&lt;a href="#cb14-27"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-28"&gt;&lt;a href="#cb14-28"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;_&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-29"&gt;&lt;a href="#cb14-29"&gt;&lt;/a&gt;            &lt;span class="dt"&gt;Chap0&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-30"&gt;&lt;a href="#cb14-30"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-31"&gt;&lt;a href="#cb14-31"&gt;&lt;/a&gt;&lt;span class="fu"&gt;parse&lt;/span&gt; : &lt;span class="dt"&gt;Chapter&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Result&lt;/span&gt; (&lt;span class="dt"&gt;List&lt;/span&gt; &lt;span class="dt"&gt;Parser&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="dt"&gt;DeadEnd&lt;/span&gt;) &lt;span class="dt"&gt;Chapter&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-32"&gt;&lt;a href="#cb14-32"&gt;&lt;/a&gt;&lt;span class="fu"&gt;eval1&lt;/span&gt; : &lt;span class="dt"&gt;Chapter&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Chapter&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-33"&gt;&lt;a href="#cb14-33"&gt;&lt;/a&gt;&lt;span class="fu"&gt;typecheck&lt;/span&gt; : &lt;span class="dt"&gt;Chapter&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-34"&gt;&lt;a href="#cb14-34"&gt;&lt;/a&gt;&lt;span class="fu"&gt;display&lt;/span&gt; : &lt;span class="dt"&gt;Chapter&lt;/span&gt; &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;List&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;あとはこれらを &lt;code&gt;Main&lt;/code&gt; でいい感じに呼び出すだけ．&lt;/p&gt;
&lt;h2 id="おしまい"&gt;おしまい&lt;/h2&gt;
&lt;p&gt;次回はいつになることやら．&lt;/p&gt;
  &lt;/div&gt;</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/12/06/postgresql-pure_%E3%82%92%E9%96%8B%E7%99%BA%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F</id><title type="text">postgresql-pure を開発しました</title><updated>2019-12-06T00:03:21+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/12/06/postgresql-pure_%E3%82%92%E9%96%8B%E7%99%BA%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F"/><summary type="html">この記事は Haskell Advent Calendar 2019 の6日目の記事です。 hackage.haskell.org postgresql-pure は Haskell の PostgreSQL ドライバー（クライアントライブラリー）で次のような目標で開発しました。 マルチコア環境でのパフォーマンス向上 暗黙のロックを回避する マルチプラットフォーム対応 C ライブラリーの libpq への依存をなくして特に Windows でのビルドを容易にする 既存ライブラリーとしては postgres-wire が高速だがそれは Windows をサポートしていない pure Haskel…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2019/12/05/191010</id><title type="text">最強にして最速のビルダー、mason</title><updated>2019-12-05T19:33:25+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2019/12/05/191010"/><summary type="html">Haskell Advent Calendar 2019 5日目 この冬、神速のサンタクロースがやってくる—— Haskellにおいて、バイト列の表現はByteStringが定番である。ByteStringはPinned領域に直接格納され、空間効率はリストに比べればはるかに良い。しかし、Pinned領域にあるとヒープフラグメンテーションが起こりやすくなるということでもあり、細かい文字列をつなぎ合わせるような使い方はパフォーマンスに悪影響が及ぶ。そのような問題を避けるため、ビルダーと呼ばれる構造が用意されている。 Data.ByteString.Builderは、word8 42 &lt;&gt; byte…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2019/11/30/215950</id><title type="text">状態機械を合成してデッドロックを検出できる Go 言語パッケージを作ってみました</title><updated>2019-11-30T21:59:50+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2019/11/30/215950"/><summary type="html">はじめに マルチスレッドで動作するプログラムの設計は難しい問題です。個々のスレッドの動作は単純に見えても、複数が並行して動作する場合の動作は組み合わせ論的に複雑になります。また、タイミングに依存する不具合は狙って再現することが難しく、通常の単体テストによる検出にも限界があります。 そんなとき、有効な手法がモデル検査です。システムの取りうる状態をあらかじめ網羅的に探索することで、「実際に動作させた際にごく低い確率で踏むバグ」であっても、動作させることなく設計段階で発見することが可能になります。 ところでちょうど先日、デッドロック発見器を自作するハンズオンに参加する機会がありました。内容は非常にシ…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/11/22/192220</id><title type="text">今日は 吉祥寺.pm20 の日です</title><updated>2019-11-22T21:51:07+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/11/22/192220"/><summary type="html">弊社での開催でしたので、自分用のメモを残しておきます。 本当は難しいPSL / hiratara 自分のセッションでした。 speakerdeck.com Windowsデスクトップでweb開発 / setoazusaさん Windowsで開発している人は少ない TypeScriptやJavaScriptならなんとかなる？ ネイティブコード、symlink、permission、ビルドスクリプトでのUNIXコマンド 大型アップデートの繰り返し。Win7とは違う VSCode のリモート WSL のデモ wsl.exe を起動 Dancer(Perl)でのデモ サーバを起動 VSCode から編…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/11/21/FFI_%E3%81%A7_Haskell_%E3%81%8B%E3%82%89_Rust_%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B</id><title type="text">FFI で Haskell から Rust を利用する</title><updated>2019-11-22T13:28:53+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/11/21/FFI_%E3%81%A7_Haskell_%E3%81%8B%E3%82%89_Rust_%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B"/><summary type="html">Rust で作ったライブラリーを静的リンクして Haskell（GHC）から使う例と説明を書いた。 github.com</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/10/23/%E6%9C%80%E8%BF%91%E3%81%AE%E8%87%AA%E5%88%86%E3%81%AE_Haskell_%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%EF%BC%88Windows%EF%BC%89</id><title type="text">最近の自分の Haskell 開発環境（Windows）</title><updated>2019-11-21T09:09:44+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/10/23/%E6%9C%80%E8%BF%91%E3%81%AE%E8%87%AA%E5%88%86%E3%81%AE_Haskell_%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%EF%BC%88Windows%EF%BC%89"/><summary type="html">id:syocy のブログを見たので Windows で自分がどうしているかをメモしておく。 syocy.hatenablog.com Stack 最近は ghcup があるがシェルスクリプト製で自分は PowerShell ユーザーなので stack を使っている。（ghcup はなんで Haskell 製じゃないんだ1？） GHC 8.8 を使うには resolver は ghc-8.8 や nightly を指定する。まだ LTS にはなっていない。 エディター エディターは Spacemacs を使っている。前は IntelliJ IDEA に HaskForce プラグインを入れて使…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/11/19/185744</id><title type="text">今日は安全なシステムプログラミング言語Rustへの招待の日です</title><updated>2019-11-19T19:11:21+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/11/19/185744"/><summary type="html">IIJさんでのセミナー を聴講に来ましたので、自分用のメモを残しておきます。 安全なシステムプログラミング言語Rustへの招待 / keenさん 2015 年に 1.0.0 がリリース ここからは安定している 6週間ごとのリリース Firefox と同じ 言語仕様は2つ Rust2015 と Rust2018 移行ツールはある。両方をコンパイルしてリンクすることも可能 実例 firecracker AWS Lambda の内側 Magick Pocket: DropBoxのストレージマネージャ Servo: レンダリングエンジン 一部が Firefox Redox : OS。 大学のプロジェク…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2019/11/18/120000</id><title type="text">開発環境構築スクリプトのCIをGitHub Actionsで回す</title><updated>2019-11-18T13:51:36+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2019/11/18/120000"/><summary type="html">小ネタですが、開発環境の構築はスクリプト化して、CIを回そうという話です。 開発環境を構築することは年にそう何回もあるわけではないですが、スクリプトを一発叩いて必要なツールが揃うようにしておくと便利です。私は素朴にシェルスクリプトで書いています。好きな言語で書けばいいと思いますが、macOSは将来的にRubyやPythonといったスクリプト言語を排除しようとしていて、不安ですね。Ansibleみたいなのを使ってもいいと思います。私はちょっと苦手で… あくまで私用のスクリプトなので使わないでください。 このスクリプトを叩いてしまえば、iTerm2やVim、tmux、自分のdotfilesの配置と…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/11/15/C_%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E4%BE%9D%E5%AD%98%E3%82%92%E6%B8%9B%E3%82%89%E3%81%99</id><title type="text">C ドライブ依存を減らす</title><updated>2019-11-17T16:13:29+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/11/15/C_%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E4%BE%9D%E5%AD%98%E3%82%92%E6%B8%9B%E3%82%89%E3%81%99"/><summary type="html">いろいろなソフトウェアがデフォルトで何でも C ドライブを使う。 C ドライブが手狭になってきたのでいくらかのデータを別ドライブに移行する方法をメモしておく。 Stack Stack（Haskell）のリソースはユーザー環境変数 STACK_ROOT の指すディレクトリーに保存される。デフォルト値は C:\sr である。パス長制限の問題があるので浅い場所がよい。D:\stack に変更した。 Stack によってインストールされる GHC や MSYS2 は LOCALAPPDATA\Programs\stack にある。これは STACK_ROOT\config.yaml に local-p…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/11/09/110030</id><title type="text">今日は Haskell Day 2019 の日です</title><updated>2019-11-09T18:10:03+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/11/09/110030"/><summary type="html">咳が止まらない状態で非常に厳しいですが、来ていますので、自分用のメモを残しておきます。 関数型(function type)を見つめるプログラミング / 山下さん 関数の型、 Haskell では第一級 リスト型 a が型なら [a] も型 タプル a b が型なら (a, b) も型 タプル a b が型なら a -&gt; b も型 a が domain 、 b が codomain 高階関数型 domain が関数 (a -&gt; b) -&gt; c codomain が関数 a -&gt; (b -&gt; c) こちらは意識されにくい 2変数関数 (a, b) -&gt; c Haskell 以外でもよく使う セク…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/11/03/121103</id><title type="text">今日は YAPC::Nagoya::Tiny 2019 の日です</title><updated>2019-11-03T18:09:50+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/11/03/121103"/><summary type="html">来ましたので、自分用のメモを残しておきます。 開会の挨拶 名古屋から来た人、東海から来た人 ランチはルーセントタワーB1が穴場 Tiny とは？ 新たなコミュニティの形成。 小規模で開催しやすい メインはトーク ハッシュタグ: #yapcjapan フロア貸切ではないので注意 Perlでもできる！ PerlウェブサービスにDocker, ECS, CDKを導入してよかったこと、大変だったこと / Windymeltさん Perlアプリケーションの環境構築は大変 plenv, MySQL Redice, Imagemagic, bzip2 などなど デザイナーさんやプランナーさん Docker-…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/10/24/Zenza_Bronica_S_%E7%B3%BB%E7%94%A8%E6%8E%A5%E5%86%99%E3%83%AA%E3%83%B3%E3%82%B0</id><title type="text">Zenza Bronica S 系用接写リング</title><updated>2019-10-24T00:43:20+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/10/24/Zenza_Bronica_S_%E7%B3%BB%E7%94%A8%E6%8E%A5%E5%86%99%E3%83%AA%E3%83%B3%E3%82%B0"/><summary type="html">Zenza Bronica S 系用接写リングの説明書（をスキャンしたものをプリントしたもの）を入手したので文字データに起こした。 docs.google.com この接写リングは4個（C-A C-B C-C C-D）で1組になっています 使用できるレンズも 40 mm～200 mm までと巾広く 標準レンズ使用の場合で等倍までの近接撮影ができます 4個の接写リングは撮影の目的に合わせ ご自由に組合せてご使用ください 別表は S2 型・C2 型カメラに 接写リングと交換レンズを組合せた場合の撮影倍率と露出倍数の関係を示します （表） ● 被写体に近接するに従って フィルム面とレンズの距離は遠く…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/10/19/171847</id><title type="text">A Regular Expression Matcher in Rust</title><updated>2019-10-19T17:18:47+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/10/19/171847"/><summary type="html">なんかの本でCで数十行のバックトラックを使った正規表現のマッチャが紹介されてた記憶があるんだけど、ビューティフルコードだったっけ？#regexfesta— hiratara (@hiratara) October 18, 2019 ということで、ソースコードが書かれている記事を見つけた。 https://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html Rust で書き直したものを文末に貼っておく。 rstfmt が if 文を改行してくれるせいで行数が膨らんでCの実装より数行長いが、ほぼ同じ感覚で書ける。 do …</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/10/18/182013</id><title type="text">今日は Regex Festa の日です</title><updated>2019-10-18T21:57:06+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/10/18/182013"/><summary type="html">今日は Regex Festa の日です Regex Festa に来ていますので、自分のためのメモを残しておきます。 挨拶 wi-fiとお手洗い、喫煙所の案内 Opt Technologies さんについて QRコード読むとアンケートあります いろいろな正規表現、いろいろなオートマトン / @sinya8282 さん 正規表現は好きだが、難しい面も面白い面もある 学部の頃は世界最速のgrepを書いてたりした 院では学術よりな研究 Shibuya.pm#16 が正規表現オンリーなイベントだった 東京素晴らしい！ 8年の時を経て復活 正規言語の魅力 オートマトンという単純な計算モデル 台数モデル…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/09/21/124858</id><title type="text">結局rustの標準入出力はどう書けばいいの？</title><updated>2019-09-21T16:07:52+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/09/21/124858"/><summary type="html">現状。 StdoutLock は LineWriter を噛んでるので、 BufWriter の意味があるのか謎。ベンチマーク取らねば。 use std::io::{self, BufRead, BufWriter, Write}; fn main() { let stdio = io::stdin(); let mut input = stdio.lock(); let stdout = io::stdout(); let mut output = BufWriter::new(stdout.lock()); let mut line = String::new(); while input…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/init-ghc-8-8-1</id><title type="text">HaskellやっていくGHC8.8.1令和元年白露の候</title><updated>2019-09-20T21:45:08+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/init-ghc-8-8-1"/><summary type="html">GHC 8.8.1 が出たので雑に環境を整えていきます。 OS: Ubuntu 18.04 LTS on VirtualBox on Windows screenshot GHC, Cabal 最近は ghcup で入れている。 $ ghcup upgrade $ ghcup list --tool all $ ghcup install 8.8 $ ghcup install-cabal latest ~/.ghcup/bin と ~/.cabal/bin にPATHが通っていない場合は通しておく。 stack は手になじまない感じがして最近使っていない。 stack のいいところとしてスク…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/09/14/171210</id><title type="text">emacsで自動改行して欲しくない</title><updated>2019-09-14T17:12:10+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/09/14/171210"/><summary type="html">特に端末へコピペとかするときに、本当に迷惑なので。 init.el をイジる。まず、 (setq indent-line-function 'insert-tab) なんて記述があったので削除（誰がなんのために入れたんだ？）。 次に、 (electric-indent-mode 0) を追加。 これでほとんどのモードで直ったのだけど、 markdown-mode だけは駄目だったので、ダメ押しの (setq markdown-indent-on-enter nil) を追加。 RET 押下時の indent-and-new-item の呼び出しを抑制できるらしい（勝手にそんなことしないで）。 …</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2019/09/07/115437</id><title type="text">単純で頑強なメッセージングシステム、franz</title><updated>2019-09-08T21:41:20+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2019/09/07/115437"/><summary type="html">Haskell製の新しいメッセージングシステムfranz(フランツ)の紹介。 github.com 背景 取引所にあるマシンで取引プログラムを実行するのが我々の仕事だが、朝8時に起動したらあとは昼寝したり酒を飲んだりというわけにはいかない。モニタリングしたり、分析のためにデータを残しておく必要がある。そのため、プログラムによって解析しやすい形でログを出力する。 今までは複数の種類のレコードをシリアライズし、一つのファイルに連結させる独自のフォーマットを10年近く使っていたが、書いていて恥ずかしくなるような多数の問題を抱えていた。 柔軟性が乏しい: 32bit整数や文字列などの単純な値しか格納で…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/09/03/190018</id><title type="text">今日はRustのLT会 Shinjuku.rs #6 @FORCIAの日です</title><updated>2019-09-03T20:32:30+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/09/03/190018"/><summary type="html">ブログ枠で RustのLT会 Shinjuku.rs #6 @FORCIA に来ています。ブログ枠が何をすればいいのかあまりわかってませんが、とりあえずブログにメモを残しておきます。 開会 会場、懇親会はフォルシア株式会社さんが提供(ありがとうございます！) 次回 11/19 で一周年 Rust初心者がRay Tracer書いてみた / keisukefukudaさん 前回も初心者、相変わらず初心者 Ray Tracer は楽しいので、新しい言語を練習するときに良い Ray Tracing とは？ 3Dのオブジェクトを平面に描画する ちゃんと計算する オフラインで時間をかけて アルゴリズム、プ…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/08/24/151450</id><title type="text">rustのcombineで入力されたトークンによる場合分け</title><updated>2019-08-24T15:14:50+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/08/24/151450"/><summary type="html">combine を使ったときに、例えば識別子のパース時に予約語を弾く方法。 最初は and_then を使うのかと思ったのだけど、 エラーの型指定がえらく面倒 だったので諦め。というか、なんか絶対違うだろうと思って別の方法を模索。 Parser のドキュメントに以下の例がある。これだ。 digit() .then(|d| { if d == '9' { value(9).left() } else { unexpected_any(d).message("Not a nine").right() } }) ということで、 then を使うと Parser を返す処理を書けるので、ここで une…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2019/08/15/195448</id><title type="text">Minecraft 1.14サーバーを運用してみた</title><updated>2019-08-15T19:54:48+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2019/08/15/195448"/><summary type="html">Minecraft 1.14 "Village and Pillage"は、サブタイトルの通り村人と略奪者をテーマにしたアップデートだ。 主な楽しみ方 村人の取引システムが一新され、以前よりもバリエーションに富み、かつリーズナブルな取引ができるようになった。余ったアイテムを換金したり、有益なアイテムを入手できるようになるだろう。 ランタン、焚火などの新たな光源や、壁や階段の変種、さらには鐘なども追加され、建築の楽しみも大きく増した。だが、良いことばかりではない――新たなイリジャー(邪悪な村人)、ピリジャーが出現するようになったのだ。条件を満たすと発生する襲撃から村を守る死闘、そして安全な拠点づ…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2019/04/04/210000</id><title type="text">Makefileの変数展開はレシピの実行前に行われる</title><updated>2019-08-14T10:31:52+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2019/04/04/210000"/><summary type="html">makeなんてよく使うものだから分かっているつもりだったけど実はよく分かっていなかったのが、変数展開がどのタイミングで行われるかということ。 itchyny.hatenablog.com Makefileでの := は simply expanded variable といって一度しか展開されないが、 = は参照するたびに展開される。 DATE = $(shell date) .PHONY: all all: @echo $(DATE) @$(shell sleep 3) @echo $(DATE) @$(shell sleep 3) @echo $(DATE) これは、 $(DATE) を参…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/08/07/120015</id><title type="text">rust の publicsuffix は遅過ぎる</title><updated>2019-08-07T12:03:57+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/08/07/120015"/><summary type="html">rust で Public Suffix List を扱うクレートの速度が遅過ぎるので、パッチを書いた。最右部のラベル ( .jp .com など) でルールを区分けして、後は愚直に線形探索という方法だったので、そりゃあ遅すぎるよねって感じ。 github.com 実は Perl の Domain::PublicSuffix でも速度の問題にあたって書き直したことがあるのだけど、このときはドメインのバリデーションが重過ぎるのが原因で、 このコミット で解消されている 1 。 rust の publicsuffix でも バリデーション は比較的重いので、この点も改善できるのかもしれない。 とこ…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/07/30/200423</id><title type="text">今日は Roppongi.rs #1 の日です</title><updated>2019-07-30T20:38:11+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/07/30/200423"/><summary type="html">職場から近いので Roppoingi.rs に来ました。自分のためにメモを残しておきます。ハッシュタグは #roppongirs 。 Rustがいかにエンジニアの脳を楽にさせているかをC++初心者が語る〜関数篇〜 / @natsu_no_yuki さん C++歴15年の初心者 rvalue reference, template特殊化などが使えるのは初心者らしい rust歴は3日 プログラミングの歴史からrustの良さを考える C言語: メモリ管理を何もしてくれない プログラマが明示的にメモリを確保したり・・・ (C、C++のことです) C++ と rust の比較 C++で関数呼び出しをする…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/07/29/%E9%96%A2%E6%95%B0%E3%81%AE%E3%83%A1%E3%83%A2%E5%8C%96</id><title type="text">関数のメモ化</title><updated>2019-07-30T13:06:40+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/07/29/%E9%96%A2%E6%95%B0%E3%81%AE%E3%83%A1%E3%83%A2%E5%8C%96"/><summary type="html">ブログに書いてみるとよく分からなくなってきました 🙃 Haskell-jp で回答をもらいました。 @lotz84_ さんの記事や GHC のプロファイルに出てくる CAF がよく分かってなかったのをまとめる。 qiita.com fact のメモ化 lotz さんの記事の階乗 fact 関数を題材にする。 fact :: Int -&gt; Integer fact 0 = 1 fact n = fromIntegral n * fact (n-1) lotz さんの記事よれば、次の実装だとメモ化されるとのこと。 -- | 関数をメモ化する関数 memoize :: (Int -&gt; a) -&gt; I…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/07/27/195704</id><title type="text">Strassen の行列積を求めるアルゴリズム</title><updated>2019-07-27T21:57:53+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/07/27/195704"/><summary type="html">アルゴリズムイントロダクションで、行列積を求める奇妙なアルゴリズムを見つけたので rust で実装した。簡単のため、行列の表現には ndarray を用いている。 #[macro_use] extern crate ndarray; use ndarray::prelude::*; type Matrix = Array2&lt;i32&gt;; type MatrixView&lt;'a&gt; = ArrayView2&lt;'a, i32&gt;; type MatrixViewMut&lt;'a&gt; = ArrayViewMut2&lt;'a, i32&gt;; fn strassen_multiply_inner (a: MatrixVi…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/07/23/225523</id><title type="text">rustのsliceとlen()</title><updated>2019-07-23T22:55:53+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/07/23/225523"/><summary type="html">こう書くと、 fn main() { let mut a = [1, 2, 3, 4, 5]; let x = &amp;mut a[3..a.len()]; println!("{:?}", x); } こう怒られる。 error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable --&gt; src/main.rs:3:23 | 3 | let x = &amp;mut a[3..a.len()]; | -----^------- | | | | | immutable borrow occurs here…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/07/06/151347</id><title type="text">rust の perl-xs を触る</title><updated>2019-07-19T16:30:43+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/07/06/151347"/><summary type="html">rust の perl-xs なるリポジトリを見つけたので触ってみた。 Perl の carton と rust の cargo が動く環境1であれば、 README に書かれている通りリポジトリを clone してきて以下で簡単に試せる。 $ carton install $ carton exec -- 'cd t &amp;&amp; perl Makefile.PL &amp;&amp; make test' perl-xs は Perl API を rust から使いやすいようにラップしたものという位置づけになる。 Perl API への低レベルなバインディングは perl-sys で提供され、 Rust のコード…</summary></entry><entry><id>https://kurokawh.blogspot.com/2019/07/mac-el-capitan.html</id><title type="text">[mac] El Capitanへのアップグレード関連作業まとめ</title><updated>2019-07-13T19:19:56.684+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2019/07/mac-el-capitan.html"/><summary type="text">YosemiteからEl Capitan（10.11.2）へアップグレードしました。旧環境で起動できていたアプリケーションが起動できなくなったり、コマンドが見つからなくなる、といった問題が発生しましたが一通り解決できたので、その内容をまとめておきます。

＃ポストし忘れてた･･･。今更な情報ですが自分の備忘録の意味もあるので公開。


El Capitanの新機能に伴う問題・設定の修正

OS X El Capitan：日本語入力のライブ変換モードをオフにする

[システム環境設定] - [キーボード]を開く
[入力ソース]タブを選択
「ライブ変換」のチェックを外す





MacPortsのアップデート

Yosemite環境でインストールしたMacPortsはそのままでは利用できない。以下のようなエラーメッセージが表示される。
% port qv installed
Error: </summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/07/07/215220</id><title type="text">rustで「サイコロを転がす」を解く</title><updated>2019-07-07T21:52:20+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/07/07/215220"/><summary type="html">最近 rust を勉強し始めたので、オフラインリアルタイムどう書くで一番簡単な問題（と思っている） サイコロを転がす を解いた。破壊的更新を戦略的に使えるのは、この程度の難易度のサンプルであれば書いてて大変気持ちがいい。 yhpg-rs/lib.rs at ord12rotdice · hiratara/yhpg-rs · GitHub</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2019/07/06/213029</id><title type="text">Docker Meetup Tokyo #31 で Kubernetes 1.15 について話してきました</title><updated>2019-07-06T21:30:29+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2019/07/06/213029"/><summary type="html">先日行われた Docker Meetup Tokyo #31 で、Kubernetes 1.15 の Scheduler 周りの新機能について発表してきました。 Kubernetes の Pod Preemption を利用すると、より重要な Pod にノードの計算リソースを割り当てる優先的に割り当てることができ、コストの最適化につながります。しかし優先度の低い Pod は実行中に強制的に終了されることとなり、長時間かかるバッチ処理が途中で中断されてしまうという弊害もあります。 本スライドでは、Kubernetes 1.15 から Alpha 機能として導入された NonPreemptingP…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2019/07/05/155146</id><title type="text">Kubernetes 1.15: SIG Scheduling の変更内容</title><updated>2019-07-05T15:51:46+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2019/07/05/155146"/><summary type="html">はじめに 本記事では、Kubernetes 1.15 のリリースノート からスケジューリングに関する内容をまとめました。 なお、SIG Scheduling の変更内容については既に他の方から翻訳記事が出ていますが、本記事は後発ということもあり、すべての機能を実際に触ってみた上でサンプルコードを添えて解説していきます。 Kubernetes 1.15: SIG Scheduling の変更内容 1.15 の新着情報 (1.15 What’s New) 今回、完全な変更ログは https://relnotes.k8s.io/ で、絞り込み可能なフォーマットで公開されています。確認とフィードバック…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/06/24/222657</id><title type="text">トレイト境界の F: FnMut(u8) -&gt; bool という記法について</title><updated>2019-06-24T22:26:57+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/06/24/222657"/><summary type="html">rust で where の中でトレイト境界を書ける。そして、クロージャはトレイトで実現されている。ってことなんだけど、クロージャを表す型変数のトレイト境界の書き方はなんとも気持ちが悪い。 struct Cacher&lt;T&gt; where T: Fn(u32) -&gt; u32 { calculation: T, value: Option&lt;u32&gt;, } Closures: Anonymous Functions that Can Capture Their Environment - The Rust Programming Language トレイト境界と言えば T: Display + Clo…</summary></entry><entry><id>https://hiratara.hatenadiary.jp/entry/2019/06/22/101608</id><title type="text">VSCodeからWSL上のRLSを使うメモ (2)</title><updated>2019-06-22T10:16:08+09:00</updated><author><name>hiratara</name></author><link href="https://hiratara.hatenadiary.jp/entry/2019/06/22/101608"/><summary type="html">ある朝突然、 cargo test が VSCode Insiders から呼べなくなった。これを踏んでた。どうやら昨日の夕方に 1.36.0-insider がアップデートされて壊れたようだ（アップデートされた記憶はあまりない）。 github.com 以下に従って5月のビルド 1.35.0-insider に戻したら問題なく動いた。 Insider らしくてとてもよい（よくない）。 Access older Insider builds · Issue #46089 · microsoft/vscode · GitHub</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2019/06/13/155557</id><title type="text">Traversable API</title><updated>2019-06-15T15:54:35+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2019/06/13/155557"/><summary type="html">与えられたConnectionを通じて、指定したKeyに対応するByteStringを取り出すような、シンプルなKey-ValueストアのAPIを考えてみよう。 type Key = ByteString fetchOne :: Connection -&gt; Key -&gt; IO ByteString ネットワーク越しにたくさんのデータを取得したいとき、何度もこれを呼び出していては効率が悪い。一度にまとめて取り出せるように拡張するなら、このように書ける。 fetchMany :: Connection -&gt; [Key] -&gt; IO [ByteString] 悪くはないが、この型はたとえば「["fo…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2019/05/29/194539</id><title type="text">Fun Fun Functional (1) で Haskell と Firebase を使ってライブコーディングしてきました</title><updated>2019-05-29T19:45:39+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2019/05/29/194539"/><summary type="html">先日行われた Fun Fun Functional (1) で、Haskell と Firebase を使った Web アプリの作り方について発表してきました。 使用した要素技術は、GHCJS 上のフレームワーク Miso と、Fireabse SDK を呼び出すための DSL である JSaddle です。 GHCJS は Haskell のソースコードを JavaScript に変換するコンパイラで、GHC をフォークすることによって開発されています。 github.com Miso は GHCJS 上で The Elm Architecture を実装するためのフレームワークです。Mis…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/04/16/%E6%8A%80%E8%A1%93%E6%9B%B8%E5%85%B8_5_%E3%81%B5%E3%82%8A%E3%81%8B%E3%81%88%E3%82%8A</id><title type="text">技術書典 5 ふりかえり</title><updated>2019-04-16T00:44:52+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/04/16/%E6%8A%80%E8%A1%93%E6%9B%B8%E5%85%B8_5_%E3%81%B5%E3%82%8A%E3%81%8B%E3%81%88%E3%82%8A"/><summary type="html">え？6？いやいや 5 ですよ？ techbookfest.org 池袋 慣れ親しんだ秋葉原の地を飛び出して池袋にやってきました。 めちゃくちゃ広くてびっくりです。秋葉原通運会館からアキバスクエアにやってきたときも思いましたが、同じ感想がもう一度。 ガラス張りじゃなくなったので外の行列見てやばいやばい言えなくなったのはほんのちょっとだけ残念です。 か61 kakkun61 という名前でもろもろアカウントを取っているのですが、今回は卓番号が「か61」ということでまさに自分のための場所でした。覚えやすい！ そんな弊卓の様子です。 落 新刊落としました…… フィルムカメラに目覚めた結果土日をそれに使っ…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2019/04/01/185927</id><title type="text">楽園へ行きたい</title><updated>2019-04-01T19:01:12+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2019/04/01/185927"/><summary type="html">楽園へ行きたい。 森と平原に囲まれた、街のはずれの小屋に住みたい。 朝は、小鳥たちのさえずりと窓から射し込む陽の光で目覚めたい。 昼は、コーヒーと焼き菓子を用意して一服したい。 夜は、天の河の向こうに思いを馳せながら眠りたい。 月曜日は大学に行き、エルフの先生の下で言語学を学びたい。 火曜日は研究室にこもり、ドラゴンの教授と研究に没頭したい。 水、木曜日は道具鍛治と修繕の仕事をしたい。 金曜日は都に向かい、品を売って食材と情報を仕入れたい。 土曜日は酒場に集まり、仲間たちと杯を交わしたい。 日曜日は使い魔を連れ、公園をゆったり散歩したい。 春は、花々を眺めながら、渡り鳥たちにしばしの別れを告げ…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/06/12/090000</id><title type="text">コマンドラインがさらに便利になるfillinコマンドを作りました！</title><updated>2019-03-22T00:59:05+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/06/12/090000"/><summary type="html">fillinというコマンドラインツールを作成しました。 コマンドの一部を変数化して、別の履歴に保存しておけるツールです。 ステージング環境と本番環境のように、同じコマンドで複数の環境を切り替えるのに便利です。 zshの本 (エッセンシャルソフトウェアガイドブック)作者: 広瀬雄二,A5出版社/メーカー: 技術評論社発売日: 2009/06/17メディア: 単行本（ソフトカバー）購入: 11人 クリック: 126回この商品を含むブログ (37件) を見る どうして作ったの コマンド履歴って便利ですよね。 私はよくコマンド履歴からコマンドを選んで実行しています。 シェルに付属しているデフォルトの履…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2019/03/21/172101</id><title type="text">特級シリアライズライブラリ、winery 1.0解禁</title><updated>2019-03-21T18:06:56+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2019/03/21/172101"/><summary type="html">fumieval.hatenablog.com あれから9ヶ月…wineryのバージョン1.0をついにリリースした。 前回までのあらすじ データの保存や通信に直列化は不可欠の概念である。 binaryなどの直列化ライブラリは、レコードのフィールド名などの情報が欠けており、構造が変わると互換性を持たせることができない。 一方、JSONやCBORなどのフォーマットで愚直にフィールド名などを残すと極めて冗長になり、時間・空間効率が悪い。 コード生成が前提のProtobufなどはHaskellの既存のデータ構造との相性がよくない。 そんな現状に殴り込みをかけたのがwineryだ。値を「スキーマ」と「デ…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2019/03/15/090000</id><title type="text">joのGo実装 gojo を作りました！</title><updated>2019-03-20T17:50:02+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2019/03/15/090000"/><summary type="html">joというJSONを組み立てるコマンドがあって、これは2016年からある便利なCLIツールなのですが、昨日急に思い立ってGo実装を作りました。 go get -u github.com/itchyny/gojo/cmd/gojo brewでもインストールできます。 brew install itchyny/tap/gojo 使い方はこんな感じ。 $ gojo foo=bar qux=quux {"foo":"bar","qux":"quux"} $ gojo -p foo=bar qux=quux { "foo": "bar", "qux": "quux" } $ gojo -a foo ba…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/03/14/159265</id><title type="text">円周率の16進数表現100億桁目を求めてみた！ ― 円周率の世界記録をどのように検証するか ―</title><updated>2019-03-15T16:17:18+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/03/14/159265"/><summary type="html">あなたは円周率を何桁言えますか。3.14159…という、あの数字です。 円周率の小数部分は無限に続き、循環することもありません。 古来より、数学者は円周率の値を様々な幾何学的な近似や公式を用いて計算してきました。 その桁数は計算機の発明により飛躍的に伸び、収束の速い公式の発見や効率の良いアルゴリズムの発明などによって加速してきました *1。 5年前、私がまだ学生だった頃、円周率1億桁の計算に挑んだことがありました。 私にとって高精度計算の初めての挑戦で、様々な試行錯誤で苦労したのをよく覚えています。 itchyny.hatenablog.com 2017年現在、円周率計算の世界記録は22兆桁で…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2019/03/01/090000</id><title type="text">gore 0.4.0をリリースしました！</title><updated>2019-03-01T09:00:03+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2019/03/01/090000"/><summary type="html">Go言語のREPL、goreの0.4.0をリリースしました。 id:motemenさんに連絡をとって、goreのコミット権をいただきました。 最初はpull requestが溜まっていたので片付けて、細かいバグ修正などを行いました。 しばらく触っていると慣れてきたので、新機能も実装して入れました。 かなり便利になっているので、ぜひアップデートして (またはインストールして) お使いください。 go get -u github.com/motemen/gore/cmd/gore バグ修正 特定のケースで Evaluated but not used というエラーが出ることがあるのを修正しました …</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/02/26/Servant_%E3%81%A8_Relational_Record_%E3%81%A7%E3%82%A6%E3%82%A7%E3%83%96%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA</id><title type="text">Servant と Relational Record でウェブアプリケーション開発</title><updated>2019-02-27T15:29:35+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/02/26/Servant_%E3%81%A8_Relational_Record_%E3%81%A7%E3%82%A6%E3%82%A7%E3%83%96%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA"/><summary type="html">Servant とは Servant は型レベルプログラミングによって、ウェブアプリとしてのインターフェースと実装との差異を防ぐことのできるウェブアプリフレームワークです。 haskell-servant.readthedocs.io 日本語記事としては lotz さんのこちらが分かりやすいので、参考にしてください。 qiita.com Haskell Relational Record とは Haskell Relational Record は言語内 DSL によって SQL を生成するもので、正しくない SQL に相当するものは型エラーとなります。 khibino.github.io こ…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2019/02/27/032421</id><title type="text">Docker Meetup Tokyo #28 で Scheduler のカスタマイズについて話してきました</title><updated>2019-02-27T03:24:21+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2019/02/27/032421"/><summary type="html">先日行われた Docker Meetup Tokyo #28で、Kubernetes Scheduler の挙動をカスタマイズする方法について発表してきました。 なお Scheduler のカスタマイズについては、つい最近 Kubernetes Meetup Tokyo #16 でも発表しています。ドキュメント類へのリンクも含めてまとめたものが以下の記事です。 ccvanishing.hateblo.jp 両方のスライドを見比べて頂ければ分かる通り、内容としてはオーバラップしている部分がかなりあります。 ただし、前回はあくまでも Scheduling Framework の解説であったのに対し…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2019/02/15/181806</id><title type="text">旅のチェックリスト</title><updated>2019-02-25T15:44:26+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2019/02/15/181806"/><summary type="html">筆者が旅に出る際に確認する項目をまとめた。 事前の準備 渡航ビザ: 必要な場合もあるので事前に確かめよう。 ESTA(アメリカの場合): どんな理由であれUSに入国する場合申請する必要がある。大抵すぐ承認されるが、遅くとも出発の72時間前に済ませるべきである。 宿: 好みに応じてホテルでもAirBnBなどで民泊を予約しても。後者はキッチンが用意されているところもある。 交通手段: 電車は大抵の場合当日で大丈夫だが、もちろん船舶や航空機の場合は予約が必須である。 冷蔵庫の整理: 日持ちしないものは消費してしまおう。 携帯するもの 財布: 財布は現金やカードを収納する。リスク回避の観点から財布は省…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2019/02/22/193916</id><title type="text">Kubernetes Meetup Tokyo #16 で Scheduling Framework について話してきました</title><updated>2019-02-22T19:39:16+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2019/02/22/193916"/><summary type="html">先日行われた Kubernetes Meetup Tokyo #16 で、現在 Scheduling SIG で進められているプロジェクト Scheduling Framework について発表してきました。 Kubernetes では、Pod をどの Node に配置するかを決める手続きをスケジューリングと呼びます。 古典的な Kubernetes の用途、すなわち通常の long-running なサーバ群の管理においては、Pod のスケジューリングは比較的シンプルな問題でした。すなわち、Node の障害時でも可用性が保てるように Pod を複数の Node に散らし、一度立ち上がった P…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2019/02/12/191002</id><title type="text">ある期間内に更新されたデータを素早く検索できるモデル</title><updated>2019-02-13T15:49:35+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2019/02/12/191002"/><summary type="html">特定の技術とは関係ない、誰でも思いつきそうな、でも便利なお話。 こんなケースを考えてみよう。 人気のトレーディングカードゲームAugur Unlimitedを扱うショップ「しらさぎ商店」では、1000種類にも及ぶカードの買い取り・販売をしている。記録のため、カードごとに日時、価格、在庫数などをまとめたレコードを毎日データベースに書き込んでいる。 新着・売り切れや、価格の変化などを、指定された期間について一覧で表示するようなWebページを作りたいとオーナーは考えた。しかし、ユーザーからの要求ごとに全データの差分を取るのは、あまり効率的な手段とはいえない。レアなカードでもない限り価格は一定であるこ…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/01/30/Haskell_Ctrl-C_%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D</id><title type="text">Haskell Windows Ctrl-C 動作確認</title><updated>2019-01-30T23:53:07+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/01/30/Haskell_Ctrl-C_%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D"/><summary type="html">コード コードは前回記事と同じです（再掲）。 Git リポジトリーはこちら。 import Control.Concurrent import Control.Monad import System.Exit import System.IO import System.Win32.Console.CtrlHandler main :: IO () main = do tid &lt;- myThreadId let handler event = do if event == cTRL_C_EVENT then do putStrLn "goodbye!" killThread tid pure …</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2019/01/25/Haskell_%E3%81%A7_Ctrl-C_%E3%82%92%E5%88%B6%E5%BE%A1%E3%81%99%E3%82%8B%EF%BC%88Windows%EF%BC%89</id><title type="text">Haskell で Ctrl-C を制御する（Windows）</title><updated>2019-01-25T11:26:15+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2019/01/25/Haskell_%E3%81%A7_Ctrl-C_%E3%82%92%E5%88%B6%E5%BE%A1%E3%81%99%E3%82%8B%EF%BC%88Windows%EF%BC%89"/><summary type="html">Ctrl-C 等の割り込みの扱い方です。 tl;dr System.Win32.Console.CtrlHandler を使います。 Ctrl-C が押されたらクロージングの処理を伴って終了するプログラムを書いてみます。 import Control.Concurrent import Control.Monad import System.Exit import System.IO import System.Win32.Console.CtrlHandler main :: IO () main = do tid &lt;- myThreadId let handler event = do i…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/try-linear-types</id><title type="text">GHCの線形型プロトタイプを試すだけ</title><updated>2019-01-08T02:01:09+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/try-linear-types"/><summary type="html">GHCに線形型を導入すると以下のような良い事があるらしい。 リソース安全性: ファイルハンドル、ソケット、DBコネクションのようなリソースについて、これらを提供するAPIの設計者が安全な使用を強制できる。リソース解放後のアクセス、二重解放、解放忘れを防止することができる。 レイテンシ: リソースAPIの実装をうまくやるとoff-heap(GCの対象外)でリソースを確保・解放できる。GC対象が少なくなることによりGCによってプログラムが停止する時間を減らせる。 並列性: 過剰な直列化を強要しない。リソース安全性を保ちつつもできる限り並列化できる。 詳しくはproposal。 この記事では線形型G…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2018/12/31/210000</id><title type="text">2018年を振り返って</title><updated>2018-12-31T21:00:02+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2018/12/31/210000"/><summary type="html">今年は仕事を淡々とこなしつつ、自分の技術の方向性に悩みながらも、ずいぶんとだらけてしまった一年だったと思います。技術面での成長に伸び悩んでいます。 Mackerelのコードの整理や改善は無限にやることがあるのですが、平日夜や休日をそれで潰す生活をしていると、頭の切り替えがうまく行かなくなり仕事中に集中できなくなってしまいました。フロントエンドはかなりコードの整理が進み、SPA化できたのはよかったですね。コンテナ周りはチョットワカルと言えるようになりたいですね。 春先にバイナリエディタをリリースしました。まだ実装したい機能はたくさんありますが、リリースしたら燃え尽きてしまってあまりコードを触れて…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2018/12/27/213853</id><title type="text">戊戌の追憶</title><updated>2018-12-28T09:01:05+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2018/12/27/213853"/><summary type="html">この記事は、筆者が過ごした2018年を簡潔に振り返り、その経験を糧とすることを狙う。 1月 第二鰓弓由来側頸嚢胞という先天異常が原因で首が化膿し、激痛に苦しんでいた。対人関係のトラブルなどもあり軽い錯乱状態にあったのか、自分が知らない間に高い買い物をすることがあった。 drinkery: Boozy streaming library というストリーム処理ライブラリを作った。当初はすべて酒関係の用語を用いていたが、批判を受けてそこはやめた。今思えばそれで正解だった気がする。 パフォーマンスはモナディックなAPIを持つライブラリの中ではトップクラスで、双方向性や多入力多出力のような発展的な機能も…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2018/12/21/201108</id><title type="text">Elias-Fano encoding: 単調増加する数列をほぼ簡潔に表現する</title><updated>2018-12-22T01:15:08+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2018/12/21/201108"/><summary type="html">Haskell Advent Calendar 2018 20日目 単調増加する自然数の列を、最低限のビット数で表現するための興味深いテクニックと、Haskellによる実装を紹介する。 Elias-Fano encoding この手法は、簡潔データ構造に分類されるもの一つであるが、厳密には条件を満たさないため疑似簡潔データ構造と呼ばれる。1970年代、Peter EliasとRobert Mario Fanoによって独立して発見された。 例題として1, 1, 4, 10, 17, 22, 23, 30という列をエンコードしてみよう。まず、それぞれの数を上位3ビットと下位2ビットに分割する。列の…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2018/12/06/195433</id><title type="text">Kubernetes 1.13: SIG Scheduling の変更内容</title><updated>2018-12-06T19:54:33+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2018/12/06/195433"/><summary type="html">はじめに 本記事では、Kubernetes 1.13 の CHANGELOG からスケジューリングに関する内容をまとめました。 主な変更点 https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.13.md#sig-scheduling 1.13 における SIG Scheduling の取り組みは主に安定性に焦点を当てており、いくつかの大きな機能の導入は次のバージョンまで延期することになりました。特記すべき変更として次に挙げる 2 点があります。 #69824: Taint based Eviction の有効化 Ta…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2018/11/24/232705</id><title type="text">We Are JavaScripters! @26th で Elm と Firebase の連携について話してきました</title><updated>2018-11-24T23:27:05+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2018/11/24/232705"/><summary type="html">先日行われた We Are JavaScripters! @19th で Elm と JavaScript ライブラリの連携について発表してきました。 Elm の初心者向けの解説としてよく Msg, Model, update からなるアーキテクチャが挙げられていますが、今回の発表ではもう一歩だけ進んで、Cmd と Sub を使って Elm から JavaScript のライブラリを呼ぶ方法について解説しました。 サーバとしての JS ライブラリ 他の AltJS では JavaScript を呼び出す際、ソースコードの内部に埋め込む形になるのが普通です。 例えば Haskell を Java…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2018/11/19/Windows_%E3%81%A7_Haskell_iconv_%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B</id><title type="text">Windows で Haskell iconv をビルドする</title><updated>2018-11-19T19:13:49+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2018/11/19/Windows_%E3%81%A7_Haskell_iconv_%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B"/><summary type="html">GHC 8.0 以前についてはこちらを参考に。 teratail.com GHC 8.2 以降で stack を使う場合をここではとりあげる。 確信はないのだが、GHC 8.2 から GHC 自体が iconv に依存しなくなったのか、$(stack path --programs)\ghc-8.0.2\mingw\lib から libiconv.a と libiconv.dll.a がなくなっているため GHC 8.0 以前のようにビルドができなくなっている。 なので、まず libiconv を取得する。 stack exec -- pacman -S libiconv-devel インスト…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2018/09/30/Leica_M3</id><title type="text">Leica M3</title><updated>2018-11-15T10:47:47+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2018/09/30/Leica_M3"/><summary type="html">Lomography Konstruktor F・Diana Mini から始まったフィルムカメラ熱ですが一瞬で行くところまで行ってしまった感じです。 Leica M3。 現在まで続く M 型 Leica の始祖を買ってしまいました。1962年製の56歳です。 （この写真を撮ったレンズも Asahi Super Takumar 55mm F1.8 なので60年代のレンズです。） Leica 意識前 初めはフィルムカメラの入門機としていくつかの記事に紹介されていた Asahi Pentax SP か Olympus OM-1（M-1）かと考えて中古カメラ屋めぐりをしていました。 このころはひたす…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2018/10/31/150056</id><title type="text">「名前の束縛」という名の束縛</title><updated>2018-10-31T18:20:45+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2018/10/31/150056"/><summary type="html">実用的なプログラミングにおいて、名前と概念を結びつける「束縛」はほぼ必須の概念である。しかし、その言葉には大きな誤解と混乱が根付いていた。 事の発端となったのは「Haskellにおいては、変数は値を代入するものではなく、値に束縛するものである」という議論である*1 *2。しかし、これは大きな誤解を孕んでいる。言葉の定義に立ち返ってその誤解を解いていこう。 束縛とバインディング 実は「束縛」には二つの意味がある。一つは、数学的な意味での変数の束縛*3、もう一つは、識別子と実体の結合という意味での束縛*4だ。 前者は変数の導入と言い換えることもできる。ラムダ計算におけるラムダ抽象と変数の関係もこれ…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2018/05/17/180426</id><title type="text">Kubernetes Meetup Tokyo #10 で Pod の Preemption について話してきました</title><updated>2018-10-23T16:31:12+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2018/05/17/180426"/><summary type="html">だいぶ日が空いてしまって今更ですが、先日行われた Kubernetes Meetup Tokyo #10 で、v1.8*1 から導入された新機能 Preemption について発表してきました。 Preemption は、Kubernetes クラスタのリソースが不足した際に、優先度が低い Pod を追い出して優先度が高い Pod の稼働を保証する仕組みです。 当日は時間が不足気味だったので、説明不十分だったかなと思われる点についていくつか補足しておきます。 Priority の指定について スライド中では詳しく説明しませんでしたが、ユーザは直接 Pod（や Deployment 中の Pod…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2018/10/15/100000</id><title type="text">Mackerelのグラフを端末で描画するコマンドmkrgを作りました</title><updated>2018-10-17T23:52:07+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2018/10/15/100000"/><summary type="html">Mackerelのグラフを端末で見れたらいいなと思ったので作ってみました。 github.com 使い方 $ go get -u github.com/itchyny/mkrg/cmd/mkrg $ mkrg コマンドを叩くと、そのホストのメトリックを取ってきてグラフを表示します。 何も考えずにコマンドを叩けば、システムメトリックのグラフを表示してくれます。 私はiTerm2を使っているので、とりあえずiTerm2では画像を表示できるようにしています。それ以外の端末では点字を使って頑張って表示します。 Mackerel サーバ監視[実践]入門作者: 井上大輔,粕谷大輔,杉山広通,田中慎司,坪内…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2018/10/02/203205</id><title type="text">猫でもわかる Vertical Pod Autoscaler</title><updated>2018-10-02T20:32:05+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2018/10/02/203205"/><summary type="html">先日行われた Kubernetes Meetup Tokyo #13 で、Vertical Pod Autoscaler (VPA) について発表してきました。 VPA は、各コンテナの Resource Request の値を自動的に調整してくれるコンポーネント群です。必要とするリソース（CPU、メモリ）量があらかじめ推測しにくいアプリケーションに対して、実績に基づいてそれらしい値を決めたい場合に効果を発揮します。 本記事ではスライドの補足として、VPA が動作する流れをクラスタ上での実際の挙動を通じて確認し、また内部実装についても踏み込んで解説します。 なお、本記事中で引用している仕様やソ…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2018/09/26/191231</id><title type="text">elm/time の使い方</title><updated>2018-09-26T19:12:31+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2018/09/26/191231"/><summary type="html">はじめに 先日、Elm v0.19 がリリースされました。公式ライブラリのリポジトリが elm-lang から elm に変更され、その中身も大きく再構成されています。 本記事では、これらの変更のうち特に時刻や日付の扱いに関する部分について、新しい API の使い方を含めて簡単に解説します。 v0.18 における時刻の扱い v0.18 では、時刻を扱う機能は標準パッケージ elm-lang/core の中で提供されていました。時刻を扱う Time モジュールと日付を扱う Date モジュールで、それぞれデータ型や関数が定義されているのが特徴です。 なお、旧バージョンのライブラリは現在 Elm …</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/konstruktor-f</id><title type="text">プラモデルカメラ Lomography Konstruktor F</title><updated>2018-09-13T16:25:09+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/konstruktor-f"/><summary type="html">本来はフジヤカメラに行くことが目的だった。 「カメラバカにつける薬 in デジカメ Watch」でも取り上げられてて、その前から気になってたのもあって中野に行った。 特に買うつもりもなかったので雰囲気だけ知れればいいやというようにそそくさと出たのだが、ジャンク館が中野ブロードウェイにあるということで行ってみた。 そういえば中野ブロードウェイも気になってたんだし一石二鳥だった。 するとコイデカメラがあった。Lomography Konstruktor F があった。 動くしくみを理解しながら自分で組み立てるのが好きでカメラも好きな自分が惹かれるのは当然という感じだった。 そのときは散財する予定は…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2018/04/27/%E6%8A%80%E8%A1%93%E6%9B%B8%E5%85%B8_4_%E3%81%AB%E3%82%B5%E3%83%BC%E3%82%AF%E3%83%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%9F</id><title type="text">技術書典 4 にサークル参加した</title><updated>2018-09-12T13:03:31+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2018/04/27/%E6%8A%80%E8%A1%93%E6%9B%B8%E5%85%B8_4_%E3%81%AB%E3%82%B5%E3%83%BC%E3%82%AF%E3%83%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%9F"/><summary type="html">4月22日に開催された『技術書典 4』にサークル参加してきました。 techbookfest.org 技術書典は1と2に個人で参加して3は会社として参加して今回の4は会社と個人と2サークルにかかわっていました。 超技術書典を抜くと皆勤です。 個人サークル 既刊として『遠回りして学ぶ Yesod 入門』を増刷し、新刊は『手続き Haskell』を持っていきました。 doujin.kakkun61.com doujin.kakkun61.com 数字 売り上げ部数は、どんぶり勘定ですが（特に Yesod 本のダウンロードカードが完全に記憶による）下記の通りとなりました。 Yesod 本 紙 + P…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2018/09/01/%E3%80%8EYesod_%E5%85%A5%E9%96%80%E3%80%8F%E5%95%86%E6%A5%AD%E8%AA%8C%E5%8C%96</id><title type="text">『Yesod 入門』商業誌化</title><updated>2018-09-01T08:26:27+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2018/09/01/%E3%80%8EYesod_%E5%85%A5%E9%96%80%E3%80%8F%E5%95%86%E6%A5%AD%E8%AA%8C%E5%8C%96"/><summary type="html">同人誌で発売していた『遠回りして学ぶ Yesod 入門』がこのたびインプレス R&amp;D より『Haskell で作る Web アプリケーション 遠回りして学ぶ Yesod 入門』として商業誌化されることになりました。 www.impressrd.jp 同人誌版からの変更点は主に、 日本語が読みやすくなった 対応バージョンが上がった 点です。章が増えたり減ったりはしていません。あと、表紙がかわいくなりました。かわいい。 商業誌では Amazon と honto にてオンデマンド印刷の紙の書籍も購入できるようになっています。紙はこれまで即売会でしか販売していなかったので初めて通信販売で買えるようにな…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2018/09/01/%E5%88%9D%E3%83%95%E3%82%A3%E3%83%AB%E3%83%A0</id><title type="text">初フィルム</title><updated>2018-09-01T07:50:07+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2018/09/01/%E5%88%9D%E3%83%95%E3%82%A3%E3%83%AB%E3%83%A0"/><summary type="html">厳密にいうと小学校の旅行などで「写ルンです」を使ったりしたことがあるので、初フィルムじゃないんだけど自分で装填するものとしては初ということで。 中野のコイデカメラで自分でプラモデルのように組み立てるカメラを見つけて「なんだこれは！？」と調べていたら Lomography にあてられてどうしても自分でも撮りたくなって中古の Lomography Diana Mini を買った。 それで2本撮ったので現像・スキャンしてもらってきた。（本当はもう1本もあったんだけどダメにした。） 70枚撮った中で奇跡的に手ぶれもなくピントも合っている1枚。 鏡筒の向かって左のレバーがシャッターボタンなんだけどこれが…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2018/08/23/211858</id><title type="text">詳解！ Elm における Fuzzing</title><updated>2018-08-23T21:18:58+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2018/08/23/211858"/><summary type="html">先日行われた We Are JavaScripters! @23rd で、Elm のテストフレームワーク elm-test に搭載されている Fuzzing 機能について発表してきました。 Fuzzing を利用するとテストデータを自動で生成することができるため、例えば「encode と decode を行うと元に戻る」といった、入力に依存しない 関数の性質に関するテスト をより簡単かつ効率的に実装することができます。 さらに、後で詳しく解説する通り、elm-test の Fuzzer にはバグが起こりやすいエッジケースを集中的に生成してくれるというメリットもあります。 elm-test の使…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2018/08/16/Windows_%E3%81%A7_haskell-ide-engine_%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B</id><title type="text">Windows で haskell-ide-engine をビルドする</title><updated>2018-08-16T17:34:50+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2018/08/16/Windows_%E3%81%A7_haskell-ide-engine_%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B"/><summary type="html">手順 1. ソースコード取得。 git clone git@github.com:haskell/haskell-ide-engine.git 2. Unicode を扱う ICU の古いバージョンが要るので取得。 自分の使うバージョンの text-icu の changelog を見て、必要な ICU のバージョンを探す。執筆時点では 53 だった。 http://site.icu-project.org/download/53#TOC-ICU4C-Download 任意の場所に展開する。以降、展開先の箇所を $icu と表記する。 $icu\bin64 にある dll の名前を変える。（要…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2018/08/01/055608</id><title type="text">July Tech Festa 2018 で分散システムの検証について話してきました / #JTF2018</title><updated>2018-08-01T13:56:39+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2018/08/01/055608"/><summary type="html">先日行われた July Tech Festa 2018 で、モデル検査を使った分散アルゴリズムの検証について発表してきました。 前半はオートマトンによるシステムの記述と検査の基礎について、後半は三種類のツール SPIN、TLA+、P による記述方法の紹介、といった内容です。 後半のソースコード紹介が散文的な感じになってしまって、いまいちメリットが伝わらない感じだったので、次回があればもっとエモいスライドにしようと思います。 分散アルゴリズムの形式化 定理証明による検証 今回の話の流れとして「分散システムにはモデル検査が有効」と述べていますが、必ずしも定理証明が分散システムの検証に向かないという…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2018/08/01/%E5%85%A5%E7%A4%BE</id><title type="text">入社</title><updated>2018-08-01T00:00:56+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2018/08/01/%E5%85%A5%E7%A4%BE"/><summary type="html">本日付けで IIJ に入社します。 職業 Haskeller になる……はず。</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2018/07/31/%E9%80%80%E8%81%B7</id><title type="text">退職</title><updated>2018-07-31T22:30:05+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2018/07/31/%E9%80%80%E8%81%B7"/><summary type="html">2013年に新卒で入社した KLab を今日付けで退職しました。</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2018/07/14/195255</id><title type="text">Dhallによるリッチな設定ファイル体験</title><updated>2018-07-14T19:52:55+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2018/07/14/195255"/><summary type="html">(この記事のレギュレーション: lts-11.9) Dhall という設定記述用言語があり、使ってみたところ良い感じだったので紹介します。 なお、この記事は先日某所で発表したものの拡大版になります。 speakerdeck.com Dhallとは何か Dhallについて短かく表現するなら公式サイトの以下の説明が分かりやすいです。 You can think of Dhall as: JSON + functions + types + imports データ表現にプログラマブルさと静的な検査とファイルのインポートを加えたものというわけです。 まだ開発中のためかあまりアピールされていませんがツー…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/11/17/090000</id><title type="text">zshの標準エラー出力の色を赤くする</title><updated>2018-06-29T14:22:55+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/11/17/090000"/><summary type="html">[追記]以下の方法は良くないようです。必ず、このエントリー最後の「stderredを使う」を参照してください[/追記] 最近stderrを赤くするように設定したら、コマンドの出力がかなり見やすくなりました。 設定はこんな感じに書いてます。 zmodload zsh/terminfo zsh/system color_stderr() { while sysread std_err_color; do syswrite -o 2 "${fg_bold[red]}${std_err_color}${terminfo[sgr0]}" done } exec 2&gt; &gt;(color_stderr) fg…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2018/06/25/130000</id><title type="text">はてな・ペパボ技術大会 #4 〜DevOps〜 @京都 で登壇しました</title><updated>2018-06-25T13:40:55+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2018/06/25/130000"/><summary type="html">先日 6/23 に技術イベント「はてな・ペパボ技術大会 #4 〜DevOps〜 @京都」で登壇・トークセッションに参加しました。 hatena.connpass.com 普段の業務でDevOpsという言葉を使うことはありません。 しかし、DevOpsのあり方を見直した結果が現状の体制や仕事のフローであったり、あるいはこれからやろうとしていることにつながっているのだと思います。 技術の進歩によりDockerやGraphQLといった、レイヤー間の共通言語が発達する中で、ソフトウェア間あるいはチーム間が疎結合になっていくことはよいです。 一方でそういう技術で解決できない場面も残っていくのだろうなと思…</summary></entry><entry><id>https://kurokawh.blogspot.com/2018/06/linuxcygwin-unzip-error-invalid.html</id><title type="text">[linux][cygwin] unzipコマンドで "error:  invalid compressed data to inflate" というエラーメッセージがでたら？</title><updated>2018-06-06T01:11:48.468+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2018/06/linuxcygwin-unzip-error-invalid.html"/><summary type="text">zipアーカイブの中に長さが0のファイルが含まれていると、unzipコマンドでは以下のようなエラーメッセージが表示されて、解凍することができません。アーカイブが壊れていなくてもエラーになります。
% unzip hoge.zip
  error:  invalid compressed data to inflate

このような場合には、-tzipオプションを指定して7zコマンドを実行することで、エラーを回避して解凍できます。パスワード保護されているzipアーカイブも問題なく解凍できました。

% 7z x -tzip hoge.zip


manページによると、以下のフォーマットがサポートされていて、デフォルトは7zとのこと。

The program supports 7z (that implements  LZMA  compression  algorithm),  
ZIP</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2018/06/03/195024</id><title type="text">日持ちする直列化のためのライブラリ「winery」</title><updated>2018-06-04T00:57:20+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2018/06/03/195024"/><summary type="html">人類は、酒と共に発展してきたと言っても過言ではない。穀物や果実などを酒に変換することにより、糖を除く栄養を保ったまま、高い保存性を持たせることができる。酒は人々の喉を潤し、時に薬として使われた。 プログラミングにおいても、終了したら消えてしまうデータを、保存性の高いバイト列に変えたい場面がよくある。そのような操作を直列化(シリアライズ)と呼び、いくつかのアプローチが存在する。 コード生成タイプ Protocol Buffers、cap'n'protoなど データの構造を記述する言語(スキーマ)から、データ構造およびシリアライザ・デシリアライザをコードごと生成する。幅広い言語で使える一方、作れる…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2018/05/24/213324</id><title type="text">We Are JavaScripters! @19th で Haskell 製フレームワーク Miso について話してきました</title><updated>2018-05-24T21:33:24+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2018/05/24/213324"/><summary type="html">先日行われた We Are JavaScripters! @19th で Haskell によるフロントエンド開発について発表してきました。 Elm の代わりにフレームワーク Miso を使うことで、クライアントサイドとサーバサイドの両方を Haskell で実装することができる、という内容です。 github.com なお今回のプレゼンでは、参加者のほとんどは Haskell に馴染みがないだろう*1ということもあって、実装上の詳細にはほとんど触れませんでした。 Elm と Miso の詳しい比較、さらに Servant と組み合わせた Isomorphic なアプリの作り方については、記事…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2018/05/18/205101</id><title type="text">JAWS DAYS 2018 で形式手法による IAM の検証について話してきました</title><updated>2018-05-18T20:51:01+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2018/05/18/205101"/><summary type="html">だいぶ日が空いてしまって今更ですが、先日行われた JAWS DAYS 2018 で登壇してきました*1。モデル検査器 Alloy を使って AWS の IAM を検証してみるという内容です。 形式手法 × AWS というテーマではこれまでにもいくつかのイベントで発表していますが、題材はネットワーク関連の検証がメインでした。 ccvanishing.hateblo.jp ccvanishing.hateblo.jp ccvanishing.hateblo.jp さすがに同じことばかり話していても芸がないので、今回は新ネタとして IAM を投入してみました。CFP も Security Slot …</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/07/31/090000</id><title type="text">ptraceシステムコール入門 ― プロセスの出力を覗き見してみよう！</title><updated>2018-05-14T18:45:57+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/07/31/090000"/><summary type="html">他のプロセスを中断せずに、その出力をミラーリングして新しくパイプで繋ぐ、そんなことはできるのでしょうか。 straceやgdbといったコマンドは一体どういう仕組みで動いているのでしょうか。 ptraceシステムコールを使い、プロセスが呼ぶシステムコールを調べて出力を覗き見するコマンドを実装してみたいと思います。 ptraceシステムコール Linuxを触っていると、いかにプロセスを組み合わせるか、組み合わせる方法をどれだけ知っているかが重要になってきます。 パイプやリダイレクトを使ってプロセスの出力結果を制御したり、コードの中からコマンドを実行して、終了ステータスを取得したりします。 プロセス…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/04/21/200000</id><title type="text">VimプラグインのTravis CIテストを複数のVimのバージョンで動かそう</title><updated>2018-03-28T10:30:13+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/04/21/200000"/><summary type="html">Vimプラグインにテストがあるのはあたりまえ。 そういう空気になってきたのはここ3年くらいのことでしょうか。 私自身、昔はあまりテスト文化に慣れておらず、「Vimプラグインみたいな小さなスクリプトにテストなんているのか？自分のプラグインは普段から使う、バグっていたらすぐ気がつくからテストなんていらないでしょ」と思っていました。 しかし、そういうテストのない自作プラグインがどんどん増えていき、3年4年と経ってしまうと自分のプラグインのコードを触りにくくなってきました。 昔はあまりVimプラグインの書き方に慣れていなかったので、酷いコードが絡み合っているのだけど、普段使う分には普通に便利なプラグイ…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/05/30/223000</id><title type="text">lightline.vimのREADME.mdを書き直しました</title><updated>2018-03-28T10:29:32+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/05/30/223000"/><summary type="html">lightline.vimはVimのステータスラインをいい感じにしてくれるプラグインです。 作って四年弱経つんですね。 おかげさまで多くのユーザーさまに使っていただいています。 itchyny.hatenablog.com github.com このREADME.mdを最近書き換えました。 ……… それだけかいな！って感じなのですが、いろいろと大変でした… 主に精神的に… つらい… プラグインを作った勢いと使って欲しいという強い思いで、プラグインを作ってすぐにREADME.mdをかなり詳しく書いていた そのために当初の設計や実装時の思いが強く出ていたが、初めてプラグインを触る人にとっては読みに…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/12/31/170000</id><title type="text">2017年を振り返って</title><updated>2018-03-28T10:27:47+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/12/31/170000"/><summary type="html">今年は仕事で関わっているプロダクトが大きな転換期を迎えて、様々な経験ができました。 ミドルウェアを自ら作り上げ、データをオンラインで移行し、運用を始めるというのはなかなか経験できないことだと思います。 サービスは以前より安定し、穏やかな年末を過ごしています。 今年は初めてカンファレンスで登壇しました。 慣れないことばかりで色々と戸惑いましたが、沢山の方に発表を聞きに来ていただいて嬉しかったです。 マネージドサービスを組み合わせて1つのソフトウェアを作り、それをサーバーレスミドルウェアとして抽象度を上げて捉えることができるようになったもの、このカンファレンスに参加してよかったことでした。 今年は…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2018/02/11/185306</id><title type="text">HaskellでDiscordのBotを作る</title><updated>2018-03-09T13:45:13+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2018/02/11/185306"/><summary type="html">Discordはゲーミング向けのテキストチャットと音声通話を兼ねるプラットフォームであり、「テキストチャンネル」と「ボイスチャンネル」の二種を好きなだけ作ることができる。もちろん音声を全チャンネルに常時垂れ流すわけには行かないので、通話するにはボイスチャンネルに参加するという手順を踏む必要がある。しかし、例えば誰かがやっているゲームに混ざろうとしてボイスチャンネルに参加しても、チャンネル外のユーザーにはいかなる通知も発生しないため、気づかれないままのことがよくある。 そこで、ボイスチャンネルに参加したとき、テキストチャンネルにその旨を投稿するボットを用意すれば、気軽に通話の合図を送れる。全員に…</summary></entry><entry><id>https://kurokawh.blogspot.com/2018/03/haskell-http-clienthaskellhttp.html</id><title type="text">[haskell] http-clientライブラリを利用してHaskellでHTTPクライアント機能を実装する</title><updated>2018-03-05T09:34:57.715+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2018/03/haskell-http-clienthaskellhttp.html"/><summary type="text">Haskellでは、http-clientライブラリを用いることで、HTTPクライアント機能を簡単に実装できます。http-client以外にも何種類かライブラリがありますが、今回はhttp-client, http-client-tlsの機能と使い方をまとめておきます。

本エントリで紹介するhttp-client, http-client-tlsライブラリの機能：

単純なHTTP GETリクエスト

主要な型の説明 

Managerのカスタマイズ 

https
proxy設定 
タイムアウト値の設定

Requestのカスタマイズ

ベーシック認証 
リクエストヘッダ 

Responseの操作

ストリーミング受信 
レスポンスヘッダの参照 

エラーハンドリング 






単純なHTTP GETリクエスト
{-# LANGUAGE OverloadedStrings #</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/12/13/170000</id><title type="text">Go言語のsyscall.Sysctlは最後のNULを落とす</title><updated>2018-03-02T17:07:49+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/12/13/170000"/><summary type="html">カーネルのパラメータを引いたり設定したりする時に便利なのが sysctl コマンドです。 $ sysctl kern.ostype kern.ostype: Darwin このコマンドのシステムコールをGo言語から叩いて、OSの種類を引いてみましょう。 func main() { ret, _ := syscall.Sysctl("kern.ostype") fmt.Printf("%s\n", ret) } Darwin 問題ないですね。 数字を返すものを叩いてみましょう。 $ sysctl machdep.cpu.feature_bits machdep.cpu.feature_bits:…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/12/23/082635</id><title type="text">猫でもわかる rkt + Kubernetes</title><updated>2018-02-28T00:36:58+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/12/23/082635"/><summary type="html">このエントリは Kubernetes Advent Calendar 2017 の 23 日目の記事です。ちなみに昨日は takezaki さんの「GCBを利用したContinuous Delivery環境」でした。 LT で使用したスライド 先日、市ヶ谷Geek★Night #16 の 10 分 LT 枠で、CoreOS 社によるコンテナ実装 rkt とその Kubernetes 連携について発表してきました。今回のエントリはこの LT の内容を補足しつつ、実際に手を動かして rkt を試せるような構成にしてあります。 Hello, rkt! rkt は、Docker の対抗馬として Cor…</summary></entry><entry><id>https://kurokawh.blogspot.com/2018/02/haskell-stack-install-cryptoniteno-such.html</id><title type="text">[haskell] stack install cryptoniteがno such instruction: `rdrand %r8'エラーで失敗する問題の対処方法</title><updated>2018-02-25T15:34:07.378+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2018/02/haskell-stack-install-cryptoniteno-such.html"/><summary type="text">手許の環境（mac）で、cryptoniteライブラリのビルドがエラーになる問題が発生したが、ネットの情報を元に解決できたので、その症状と手順をblogに残しておく。



エラーの症状：
stack install cryptoniteで以下のようなエラーが発生。
% stack install cryptonite
--  While building custom Setup.hs for package cryptonite-0.24 using:
      /Users/xxx/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_2.0.1.0_ghc-8.2.2 --builddir=.stack-work/dist/x86_64-osx/Cabal-2.0.1.0 build --ghc-options " </summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2017/12/25/%E3%81%AA%E3%81%9C_Haskell_%E3%81%8C%E5%A5%BD%E3%81%8D%E3%81%AA%E3%81%AE%E3%81%8B</id><title type="text">なぜ Haskell が好きなのか</title><updated>2018-02-25T14:53:18+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2017/12/25/%E3%81%AA%E3%81%9C_Haskell_%E3%81%8C%E5%A5%BD%E3%81%8D%E3%81%AA%E3%81%AE%E3%81%8B"/><summary type="html">自分は Haskell が好きで休日は Haskell を書いています。そういうことを言うと関数型が好きなんですねと言われるのですが、Haskell のよさはそこじゃないと感じているので書き起こそうかと、筆を執りました。 というわけで、この記事は技術的文書というよりもお話です。Haskell を知らない人向けです。 この記事は Haskell Advent Calendar 2017 その3の6日めの記事です。6日が過ぎても担当のいない日だったため担当します。 関数型プログラミングだから Haskell が好きというわけではない まず、「Haskell というと手続き型とは全然違う関数型なんで…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2018/02/14/160833</id><title type="text">Haskellの実行バイナリにファイルを埋め込む</title><updated>2018-02-14T16:12:25+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2018/02/14/160833"/><summary type="html">コンパイルしてできる実行バイナリにファイルを埋め込みたいことがある。
アプリのGUIで使うアイコンとか機械学習の学習済みモデルとか。
Go では (現在では非推奨らしいが) go-bindata を使う場面だろうか。

Haskell ではそういうときには [file-embed](https://hackage.haskell.org/package/file-embed) パッケージが使える。
たとえば `[project root]/resources/lorem.txt` に置かれた [lorem ipsum](https://ja.wikipedia.org/wiki/Lorem_ipsum) テキストを埋め込む場合:</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2018/01/27/%E5%BC%8A%E5%90%8C%E4%BA%BA%E3%82%B5%E3%83%BC%E3%82%AF%E3%83%AB%E3%81%AE%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B5%E3%82%A4%E3%83%88%E3%82%92%E4%BD%9C%E3%82%8A%E3%81%BE%E3%81%97%E3%81%9F</id><title type="text">弊同人サークルのウェブサイトを作りました</title><updated>2018-01-28T12:39:56+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2018/01/27/%E5%BC%8A%E5%90%8C%E4%BA%BA%E3%82%B5%E3%83%BC%E3%82%AF%E3%83%AB%E3%81%AE%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B5%E3%82%A4%E3%83%88%E3%82%92%E4%BD%9C%E3%82%8A%E3%81%BE%E3%81%97%E3%81%9F"/><summary type="html">がんばった。 doujin.kakkun61.com GitHub Pages だからと Jekyll にしたけど、生成したものを置けばいいんだから Hakyll でもよかったな。変えようかなというところ。 後はレスポンシブ対応したい。</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2017/12/24/202404</id><title type="text">ガバガバAltJSを作った(言語実装 Advent Calendar 2017)</title><updated>2017-12-24T20:27:10+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2017/12/24/202404"/><summary type="html">qiita.com JavaScriptを書いていると、頻出する継続渡しのリフレインにうんざりさせられる。 foo.bar(function(result){ qux.baz(function(data){ hoge(function(r){ ... }); }); }); そこで、腕試しに継続モナドをベースにしたAltJS、jatkoを作った。フィンランド語で「継続」という意味だ(継続戦争から知った人も多いだろう)。しかし、なんの考えもなしに653行Haskellを書いた結果ガバガバな言語になってしまった。 Hello, world Haskellにだいぶ近いのでなんとなく読めるはず。 in…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2017/12/19/203500</id><title type="text">HaskellのABC(Haskell Advent Calendar 6th)</title><updated>2017-12-19T20:35:00+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2017/12/19/203500"/><summary type="html">Haskellといえば一文字変数名、一文字変数名といえばHaskellという{{要出典}}ほどにHaskellでは一文字の変数名がよく使われている。これは名前を考えるのをサボっているとは限らない。多相性によって変数が具体的な性質を持たないがゆえに、具体的な名前がつけられないというのが主な理由だ。あるいは、適切な名前があっても、既存の名前と被っているという場合もある。かといって完全なランダムというわけでもないので、一文字変数名はどのように選べばいいか考察していこう。 a よくある種: * アルファベットの最初であるaは汎用性が高い。型変数に使うのが王道だ。値レベルの変数として単体で使うことは意外…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/12/12/170000</id><title type="text">Go言語のHTTPリクエストのレスポンスボディーとEOF</title><updated>2017-12-12T18:16:42+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/12/12/170000"/><summary type="html">Reader interface の Read 関数は、どのタイミングで io.EOF を返すのでしょうか。 まずは strings.Reader で見てみましょう。 package main import ( "fmt" "strings" ) func main() { r := strings.NewReader("example\n") for { var b [1]byte n, err := r.Read(b[:]) fmt.Printf("%d %q %v\n", n, b, err) if err != nil { break } } } 結果 1 "e" &lt;nil&gt; 1 "x…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2016/07/02/174426</id><title type="text">Haskellの最近の例外ハンドリング</title><updated>2017-12-06T17:19:02+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2016/07/02/174426"/><summary type="html">どうもHaskellには標準のControl.Exceptionモジュールだけでなくmtlやexceptionsやexceptionalといった例外を扱うためのパッケージがあるらしいのだが、そのあたりのパッケージの選び方や使い方についてまとまった情報を見つけられなかった。 HaskellWiki例外のページも少々古いようで、deprecatedなものや統合される前のパッケージを書いていたりする。 調べた限り、mtlとexceptionsが今の主流っぽい。 その2つの使い方をまとめる。 なおバージョンはlts-6.1を基準としている。 mtl mtlパッケージのControl.Monad.Exc…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2016/08/28/175500</id><title type="text">続・Haskellの最近の例外ハンドリング</title><updated>2017-12-06T17:18:53+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2016/08/28/175500"/><summary type="html">前回 の記事ではHaskellの例外ハンドリングには exceptions パッケージを使えばいいのではないかと書いた。 ところが今年の6月に safe-exceptions という exceptions を拡張したようなパッケージがさる FPComplete から 発表 された。 そこでこの記事では safe-exceptions について調べてみる。 おそらくほぼ FPComplete の発表の受け売りになってしまうので英語を読める人は原文を読む方がいいかもしれない。 さすが FPComplete だけあってこれは既に LTS Haskell に入っている。 この記事では lts-6.14…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/haskell-library-2016</id><title type="text">Haskellライブラリ所感2016</title><updated>2017-12-06T17:18:40+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/haskell-library-2016"/><summary type="html">(これは Haskell Advent Calendar 2016 の7日目の記事です) 今年使ったり調べたりした Haskell ライブラリを広く紹介していく企画です。 あくまで今年使ったものなので新しいものばかりではないです。 また記事の性質上、紹介するものが偏っていてもご容赦ください。 Hackage にはすごい数のライブラリが登録されていて、 頼もしいことですが目が回りそうにもなってしまいます。 この記事が Haskell のライブラリを調べる上での指針になったら幸いです。 なおこの企画と方向性が似ているものとして State of the Haskell ecosystem ( 20…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2017/04/26/005415</id><title type="text">超技術書典でGHCJSの本を出します</title><updated>2017-12-06T17:18:31+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2017/04/26/005415"/><summary type="html">【告知】ニコニコ超会議2017と併催される超技術書典Day1(4/29)にて、GHCJSの入門的な本を出します。@y_taka_23 さんのスペースに委託する形になります。Haskell×JavaScriptに興味のある方はぜひA-04まで。 #技術書典 #超技術書典 pic.twitter.com/zUhiVc3CyX — しょしー 超技術書典A-04 (@syocy) 2017年4月25日 出します。 GHCJSの仕組みの話はほとんどなくて、あくまで使い方とか周辺事情の話になります。 GHCJSって昔は導入すること自体が難しくて、他のHaskell系AltJSに水をあけられている感があった…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2017/05/20/025021</id><title type="text">Haskellは真面目なアプリケーション開発に向いている</title><updated>2017-12-06T17:18:19+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2017/05/20/025021"/><summary type="html">qiita.com ↑の記事で（主題ではないと思うものの）Haskellの批判に結構な分量が割かれていて、その批判のなかに「ちょっと違うんじゃないかな」という点がいくつかあったので反論ぽいことを書きます。 "Haskell は真面目なアプリケーション開発には向いてない"について これには多分いくつか事例を挙げればよくて、 Facebook ではスパム等の攻撃と戦うためのシステムを Haskell で作っています。 Fighting spam with Haskell | Engineering Blog | Facebook Code | Facebook (この記事を書いている Simon …</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2017/08/14/235830</id><title type="text">HaskellとJSON、そしてレコード型</title><updated>2017-12-06T17:18:07+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2017/08/14/235830"/><summary type="html">HaskellのJSON周りについて、こうやるのがいいんじゃないかという私の現在のやり方を書きます。 題材としては、 Swagger Petstore に記されている REST API にリクエストを投げてレスポンスを取り出すというのをやります。 (Swagger ですが scaffold は使わず自分で HTTP クライアントライブラリを使います)。 基本方針は「出力は厳密に入力には寛容に」(出典失念) です。 もくじ JSONの前に: レコードのフィールドへのアクセス JSONの前に: レコードのデフォルト値 Haskellのデータ型→JSON JSONデータを含むHTTPリクエスト レス…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2017/08/27/003035</id><title type="text">GoのTickerみたいなやつをHaskellで作った</title><updated>2017-12-06T17:17:55+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2017/08/27/003035"/><summary type="html">github.com 作った。 GoのTickerはとてもシンプルな関数で、 指定した周期でチャネルに値を送るスレッドを生成する。 一定間隔で何かの処理を行いたいときに利用する。 今回作ったHaskell版もだいたい同じようなものを提供する。 実際のところパッケージにするには小さすぎる気もするけど、 Haskellパッケージ製作の練習をしたかったのでHackageのアカウントを取ってHackageに上げた。 練習のため、HaddockによるAPIドキュメントおよびhspecとdoctestによるテストも書いてある。 あとは何かCIを導入してGithubのページにCIのステータスを表示するような…</summary></entry><entry><id>http://syocy.hatenablog.com/entry/a-tour-of-go-in-haskell</id><title type="text">A Tour of Go in Haskellを作ったのと、GoとHaskellの比較</title><updated>2017-12-06T17:17:38+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/a-tour-of-go-in-haskell"/><summary type="html">A Tour of Go in Haskell (日本語版/英語版) というサイトを作ったので、それの紹介をします。 https://a-tour-of-go-in-haskell.syocy.net/ja_JP/index.html Haskell は Go と同じく軽量スレッドやチャネルの機能があり、並行並列が得意な言語です。このサイトは A Tour of Go という Go のチュートリアルの並行性の章を題材として２つの言語を比較しています。</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/12/04/044908</id><title type="text">NGK2017B で Liquid Haskell について話してきました</title><updated>2017-12-04T04:49:08+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/12/04/044908"/><summary type="html">先日、毎年恒例のなごや LT 大会 NGK2017B / 名古屋合同懇親会 2017 忘年会 で発表してきました。 Liquid Haskell で普通の型システムの上を行け #NGK2017B from y_taka_23 www.slideshare.net 当日の動画は NGK2017B 第2部 - YouTube から見ることができます。 ちなみに NGK での発表は 5 年連続 5 回目です。前回まではモデル検査をテーマにしていましたが、今回はちょっと目先を変えて（とはいえ同じ形式手法の枠内ですが）もう少しプログラム寄りの題材として Liquid Haskell を選びました。 N…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/11/27/070558</id><title type="text">現在時刻をモックする Haskell ライブラリ time-machine を作ってみました</title><updated>2017-11-27T07:05:58+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/11/27/070558"/><summary type="html">主としてテスト時のために、現在時刻を操作する Haskell ライブラリを作成しました。Hackage にも登録済みです。 github.com 試しに次のコードを実行してみましょう。getCurrentTime しているはずなのに、返ってくる値が 1985 年 10 月 26 日になっているはずです。 module Main where import Control.Monad.TimeMachine import Control.Monad.Trans ( liftIO ) main :: IO () main = backTo (the future) $ do t &lt;- getCurr…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/11/06/090000</id><title type="text">Serverlessconf Tokyo 2017で『サーバレスアーキテクチャによる時系列データベースの構築と監視』という発表してきました</title><updated>2017-11-06T14:01:24+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/11/06/090000"/><summary type="html">先日開催されたServerlessconf Tokyo 2017にスピーカーとして参加しました。 2017.serverlessconf.tokyo Mackerelの今の時系列データベースは、マネージドサービスを組み合わせて作っています。 検証・実装・投入フェーズを終えて、運用・新機能開発フェーズに入っています。そんな中で、監視サービスを提供する私たちが、サーバーレスアーキテクチャで作ったミドルウェアをどのように監視しているかについてお話しました。 何かしら役に立つことや発想の元となるようなことをお伝えできていたらいいなと思います。 私も他の発表から様々なことを学びました。特に面白かった発表…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/10/25/033444</id><title type="text">技術書典 3 で新刊落としました</title><updated>2017-10-25T03:34:44+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/10/25/033444"/><summary type="html">先日、秋葉原で開催された技術系同人誌のオンリーイベント 技術書典 3 にサークル参加しました。 本当は新刊として Scala 用の静的解析ツール Stainless の入門書を頒布する予定で、サークルカットも完全にその線で準備していたのですが、残念ながら諸事情につき完成しませんでした。 事前にサークルチェックしてくださっていた 36 名の方々には大変申し訳ありませんでした。チェシャ猫先生の次回作にご期待ください。 何も並べるものがないのはちょっとどうかと思ったので、当日は 前回の技術書典 2 で頒布 した既刊『入門 LiquidHaskell』の PDF 版（ダウンロードカード）を持ち込みまし…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/10/18/202148</id><title type="text">Serverless Meetup Tokyo #6 で Kubernetes について話してきました</title><updated>2017-10-21T02:14:23+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/10/18/202148"/><summary type="html">先日行われた Serverless Meetup Tokyo #6 で、Kubernetes 上で動作する Serverless フレームワーク Fission について発表してきました。 Fission で 始める Containerless Kubernetes #serverlesstokyo from y_taka_23 www.slideshare.net 先週も 似たようなブログ を書いたような気がしなくもないですが、Kubeless と Fission を比較した前回の発表に対し、今回は話題を Fission に限定しています。一方で追加要素として、複数の Function を組…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2017/10/17/172322</id><title type="text">ステートマシン猛レース</title><updated>2017-10-19T18:19:14+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2017/10/17/172322"/><summary type="html">ストリーム処理ライブラリはHaskellにおいて競争の激しい分野の一つだ。ストリーム処理ライブラリとは大雑把に言うと、IOなどの作用を絡めながら値の列(ストリーム)を生成したり、処理したりする構造を提供するライブラリである。多くのライブラリは、以下の3種の構造を定義している。 生産者(プロデューサー): IOなどのアクションを伴いつつ値を生成する。 消費者(コンシューマー): 多くの場合モナド変換子になっており、await :: Consumer s m sのようなアクションを組み合わせ、値の列を処理するプログラムを書ける。 変換者(トランスデューサー): 入力を受け取りながら、出力もできる。…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/10/14/092409</id><title type="text">Kubernetes Meetup Tokyo #7 で Serverless について話してきました</title><updated>2017-10-14T09:24:09+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/10/14/092409"/><summary type="html">先日行われた Kubernetes Meetup Tokyo #7 で、Kubernetes 上で動作する Serverless フレームワークについて発表してきました。 Kubernetes でも Serverless したい！ #k8sjp from y_taka_23 www.slideshare.net Serverless on Kubernetes を謳うツールはいくつかありますが、今回はそのうち Kubeless と Fission に焦点を当て、それぞれのアーキテクチャの違いを比較してみました。 当日の補足 Twitter 上で反応をもらった点についていくつか補足します。 Fu…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2017/10/11/230117</id><title type="text">WindowsでのHaskell開発環境構築(2017年秋版)</title><updated>2017-10-13T23:20:39+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2017/10/11/230117"/><summary type="html">身の丈に合わないと形容されても仕方ないようなハイスペックなPCを買った。開発環境は当然作り直すことになるので、その軌跡を残しておく。 MSYS2 まずはMSYS2を入れる。これでツールチェーンが揃い、minttyというターミナルエミュレータもついてくる。 $ pacman -Syuu $ pacman -Sy git stack Haskellのビルドツールであるstackのインストーラを入手する。処理系から依存パッケージまで無難かつ自動的に用意してくれるので便利だ。 Home - The Haskell Tool Stack ただしstackはMSYS2上ではうまく動作しない。設定ファイル(…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/10/10/100000</id><title type="text">負荷を均すための『時間軸シャーディング』という考え方</title><updated>2017-10-10T10:46:10+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/10/10/100000"/><summary type="html">ウェブアプリケーションを作っていると、負荷を分散させるために「タイミングをばらけさせる」場面に時々遭遇します。 データの更新、キャッシュのフラッシュ、バッチ処理など様々な問題で、同じ構造が見られます。 例えば、スマホアプリからバックグラウンドで1時間ごとに何らかの情報をサーバーに送りたいとします。 愚直に毎時0分に更新処理を行うようにすると、すべてのユーザーから同じタイミングでリクエストが来てしまいます。 ですから、リクエストのタイミングをユーザーごとにばらして負荷を均す必要があります。 他のケースを考えます。 5分ごとにジョブを投入して何らかの更新を行うタスクがあるとします。 本来ならデータ…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/10/05/090000</id><title type="text">Mackerelのプラグインを書く楽しみ ― Rustでプラグインを書くためのライブラリを作りました！</title><updated>2017-10-07T14:43:39+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/10/05/090000"/><summary type="html">Mackerelは「エンジニアをワクワクさせる」ツールであることをサービスの大事な考え方の一つとして捉えています。 一体どういう場面でエンジニアはワクワクするのでしょうか。 簡単にインストールできるmackerel-agentや、直感的で触りやすい画面、チャットツールとの連携は大事な機能です。 しかし、監視ツールとしてもっと重要なのは、ミドルウェアのメトリックをどのように可視化し、何を監視するかということです。 Mackerelは公式のプラグインリポジトリに各種プラグインを揃えています (contributorの皆様ありがとうございます)。 これらはすべてGo言語で書かれています。 しかし、M…</summary></entry><entry><id>http://lotz84.github.io/posts/an-introduction-to-haskell-for-engineers.html</id><title type="text">エンジニアのための『Haskell入門』</title><updated>2017-10-03T00:00:00Z</updated><author><name>lotz</name></author><link href="http://lotz84.github.io/posts/an-introduction-to-haskell-for-engineers.html"/><summary type="html"></summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2017/08/15/C%23_%E3%81%A7%E3%83%A9%E3%83%B3%E3%82%AF_N_%E5%A4%9A%E7%9B%B8</id><title type="text">C# でランク N 多相</title><updated>2017-09-25T06:24:00+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2017/08/15/C%23_%E3%81%A7%E3%83%A9%E3%83%B3%E3%82%AF_N_%E5%A4%9A%E7%9B%B8"/><summary type="html">追記：これだと解決できていない。 C# に Sprache というパーサーコンビネーターがあるのだが、最近そいつを継続渡しスタイル（continuation passing style; CPS）にしてやろうと、Haskell のパーサーコンビネーター attoparsec を参考にいじっていた。 そこでこういう型があった。 newtype Parser i a = Parser { runParser :: forall r. State i -&gt; Pos -&gt; More -&gt; Failure i (State i) r -&gt; Success i (State i) a r -&gt; IResu…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/09/14/150435</id><title type="text">Haskell ライブラリにスターを送るツール thank-you-stars を作ってみました</title><updated>2017-09-14T15:04:35+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/09/14/150435"/><summary type="html">Haskell の GitHub レポジトリを眺めてみると、有名ライブラリであってもスター数が意外と少ないことがあります。かの Yesod ですら本記事執筆時点で 1,794 個であり、Rails の 36,933 個や Django の 28,165 個と比較すると文字通り桁違いです。 スター数は必ずしも OSS としての評価や価値を反映しませんし、そもそも Haskell ユーザの絶対数が少ないからと言ってしまえばそれまでなのですが、若干寂しい感じがしません？ 一方、先日 id:teppeis さんが 依存しているライブラリにスターを送る npm ツール を公開されていました。そこで真似し…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2017/08/06/154901</id><title type="text">FRPクライシス</title><updated>2017-08-06T18:18:29+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2017/08/06/154901"/><summary type="html">FRP(Functional Reactive Programming)は、リアクティブプログラミングと関数型プログラミングの性質を持つプログラミングパラダイムである。FRPは古典的FRPと矢矧のFRPに大別される。 古典的FRP 古典的(Classical)FRPは、非連続的な値の列Eventと、常に何らかの値を取るBehaviourの二種類の構造を導入したものである。 代表的な実装としてreactive-banana、euphoria、reflexなどが挙げられる。 Haskellにおいては、EventはIOを通じて非同期的に生成できる設計が多い。Eventはマップやフィルタリングができ、…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2017/08/02/230422</id><title type="text">快速のExtensible effects</title><updated>2017-08-03T08:52:52+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2017/08/02/230422"/><summary type="html">extensibleは拡張可能レコードだけでなく拡張可能作用(extensible effects)も用意している。拡張可能作用は一時期Haskell界隈で話題になったものの、今では人気も下火になってしまった。新しいバージョンをリリースした今、拡張可能作用の動機と使い方について改めて紹介しよう。 難行の一次関数 Haskellでモナドをカスタマイズする方法としては、transformersのモナド変換子がよく使われている。モナド変換子は、モナドをパラメータとして取り、新たな能力を付与したモナドにする構造だ。例えば、StateT sはモナド変換子の一つである。任意のアクションm aはliftを使…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2017/07/08/%E2%80%9Cmeaningless_REX_prefix_used%E2%80%9D_%E2%80%9Cuse_of_REX.w_is_meaningless%E2%80%9D</id><title type="text">“meaningless REX prefix used” “use of REX.w is meaningless”</title><updated>2017-07-09T00:20:11+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2017/07/08/%E2%80%9Cmeaningless_REX_prefix_used%E2%80%9D_%E2%80%9Cuse_of_REX.w_is_meaningless%E2%80%9D"/><summary type="html">コマンドプロンプトや PowerShell でプログラムを実行したときに次のようなエラーが出て困っていた。 [0x7FFE822C2B00] ANOMALY : meaningless REX prefix used [0x7FFE85B3DDA0] ANOMALY : use of REX.w is meaningless (default operand size is 64) REX プレフィックスとは何ぞや。 ロングモードでは、64ビット化するにあたり、16ビット時代から存在した1バイトのinc/dec命令であるinc reg16/dec reg16命令(op 0x40〜0x4f)を廃…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/06/19/090000</id><title type="text">音量を調節できるCLIツールをGo言語で作りました！</title><updated>2017-06-19T09:01:35+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/06/19/090000"/><summary type="html">volumeコマンドを作りました。 音量の調整ってコマンドからどうやるんだろう、ポータブルな形でコマンドラインツールがあれば便利なのでは… と思ったので作りました。 macOSとUbuntuで動作確認をしています。 インストール go get -u github.com/itchyny/volume-go/cmd/volume getは今の音量を返します。set (0-100) で音量を設定できます。 $ volume get 25 $ volume set 20 $ volume get 20 up, down, mute, unmuteなど、直感的に使えるサブコマンドを揃えています。 $ …</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/06/07/210000</id><title type="text">Vimに自分の書いたパッチが取り込まれた！</title><updated>2017-06-08T15:33:13+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/06/07/210000"/><summary type="html">Vim 8.0.0623に私の書いたパッチが取り込まれました。 わーい ∩(＞◡＜*)∩ わーい！ もともとのきっかけは、自分のプラグインを開発している中で、[\u3000-\u4000]という正規表現に対する挙動がset re=1とset re=2で違うことに気がついたのです。 Vimは正規表現エンジンを2つ積んでいる恐ろしいエディターなのですが、この2つの正規表現エンジンの挙動に微妙な違いがあることに気がつきました。 新しいNFAエンジンではエラーは出ませんが、古いエンジンではエラーが出ます。 古い正規表現エンジンでは、[a-z] みたいなパターンで、[\u3000-\u4000]のように…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2017/05/22/%E9%96%A2%E4%BF%82%E3%81%A8%E4%BB%A3%E6%95%B0%E7%9A%84%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B%E3%81%A8%E3%81%AE%E7%9B%B8%E4%BA%92%E5%A4%89%E6%8F%9B%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E5%A6%84</id><title type="text">関係と代数的データ型との相互変換についての妄想 その3</title><updated>2017-05-22T10:11:04+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2017/05/22/%E9%96%A2%E4%BF%82%E3%81%A8%E4%BB%A3%E6%95%B0%E7%9A%84%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B%E3%81%A8%E3%81%AE%E7%9B%B8%E4%BA%92%E5%A4%89%E6%8F%9B%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E5%A6%84"/><summary type="html">思い付き その2 class QueryUser ? where queryUser :: (?) =&gt; Key -&gt; MonadDB User instance QueryUser ? where -- queryUser :: (HasFriends ?) =&gt; Key -&gt; MonadDB User query = … instance QueryUser ? where -- queryUser :: (HasName ?) =&gt; Key -&gt; MonadDB User query = … userFriends :: (HasFriends ?) =&gt; User -&gt; [User] …</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/05/21/120000</id><title type="text">Haskellで10を作るプログラムを書いてみたので動画で公開してみた</title><updated>2017-05-21T23:25:27+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/05/21/120000"/><summary type="html">最近Rui Ueyamaさんがコーディング動画をアップされているのを見て、私も動画を撮りたくなりました。題材をしばらく考えていたんですが、10を作るプログラムを書いてみることにしました。 www.youtube.com 後から見直すと色々ミスっていて、わりと焦っていることがわかります。なにかの癖で適当に bc -l とかやったのだけど、音声をあてる時は関係ないオプションだと勘違いしてしまいました。確かにglobされていたのはよくなかったけど、 echo '5 / (5 / (5 + 5))' | bc -l とかで考えてみると -l も必要なんですよね。2つの問題が起きていて混乱してしまった……</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/05/21/150903</id><title type="text">JJUG CCC 2017 Spring で Haskell on JVM について話してきました</title><updated>2017-05-21T15:14:00+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/05/21/150903"/><summary type="html">先日行われた JJUG CCC 2017 Spring で、JVM 上で動作する Haskell について発表してきました。 思ったほど怖くない！ Haskell on JVM 超入門 #jjug_ccc #ccc_l8 from y_taka_23 www.slideshare.net メインになるコンテンツはふたつの JVM 言語、Frege と Eta です。 今回はあくまでも Java のイベントなので、発表前半では Haskell の基本概念、特にモナドについてそれなりの時間を割いて説明してみました。さらにそれを踏まえて後半ではモナドを利用した Java ライブラリの呼び出しに焦点を…</summary></entry><entry><id>https://itchyny.hatenablog.com/entry/2017/05/07/100000</id><title type="text">gitのファイル変更日時をファイルのアクセス日時に設定</title><updated>2017-05-07T10:00:11+09:00</updated><author><name>itchyny</name></author><link href="https://itchyny.hatenablog.com/entry/2017/05/07/100000"/><summary type="html">普段使っているファイラーはファイルのアクセス日時でソートされるように設定しています。大きめのリポジトリをcloneしてコードを読む時に、意外とファイルの最終変更日時が参考になったりします。仕事で使うリポジトリや、定期的にpullしているなら、徐々に変更のないファイルはファイラーの下の方に移動していく (上の方からアクセス日時の降順として) のですが、cloneしたばかりだとこうは行きません。 要はgitリポジトリ内の各ファイルのアクセス日時を、そのファイルのgit履歴上での最終変更日時に戻したいという気持ちになるわけです。そうするとファイラー上でもいい感じにファイルがソートされるのです。 #!…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/05/06/060400</id><title type="text">超技術書典で同人誌『入門 LiquidHaskell』を頒布できませんでした</title><updated>2017-05-06T06:04:00+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/05/06/060400"/><summary type="html">先日、ニコニコ超会議内で行われた「超技術書典」にて、LiquidHaskell の同人誌でサークル参加してきました。 lh101.dodgsonlabs.com 技術書典 2 ではそこそこの部数が出た ので Haskell 同人誌の需要はゼロではないと踏んでいたのですが、びっくりするぐらい売れません でした。とりあえず後に続く人が同じ轍を踏まないように、今回の様子について記録しておきます。 頒布物 頒布した同人誌は以下の 2 種類です。前者は技術書典 2 で頒布したものの増刷、後者は id:kazeula さんから委託を受けた新刊です。 入門 LiquidHaskell −篩型による静的コード…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2017/04/11/044041</id><title type="text">技術書典 2 で同人誌『入門 LiquidHaskell』を頒布しました</title><updated>2017-04-11T04:40:41+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2017/04/11/044041"/><summary type="html">先日、秋葉原で行われた技術書のオンリーイベント「技術書典 2」にて、LiquidHaskell の同人誌を頒布してきました。 lh101.dodgsonlabs.com LiquidHaskell は、SMT ソルバをバックエンドとして利用することで、Haskell の持つ型の表現力をより強化する仕組みです。通常の Haskell では型情報としてエンコードできない値レベルの制約を記述できるため、例えば「0 でない Int 型」を定義すればゼロ除算をコンパイル時に検知できます。以前の記事 にちょっとした解説があります。 当日は冊子版を 30 冊と PDF 版ダウンロードカードを 50 シリアル…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2017/03/11/232319</id><title type="text">generateの罠</title><updated>2017-03-11T23:24:28+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2017/03/11/232319"/><summary type="html">vectorパッケージのData.Vectorにはgenerateという関数がある。 generate :: Int -&gt; (Int -&gt; a) -&gt; Vector a 型から全てを知ることはできないが、だいたい想像通りgenerate n fは[f 0, f 1, f 2, ...f (n - 1)]からなるVectorを生成する。しかし、これは要素を評価はしない。生成されるのはあくまでサンクのVectorだ。 Prelude &gt; import Data.Vector as V Prelude V&gt; V.length $ V.generate 5 (const undefined) 5 ve…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2016/12/24/193038</id><title type="text">LiquidHaskell コトハジメ</title><updated>2016-12-25T15:06:06+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2016/12/24/193038"/><summary type="html">このエントリは Haskell Advent Calendar 2016 および Formal Method Advent Calendar 2016 の 23 日目の投稿です。のはずでしたがすでに日付が変わりました。謹んでお詫び申し上げます。 ちなみに 22 日目の担当者はそれぞれ Haskell Advent Calendar 2016 : heredocsの紹介 - Qiita Formal Method Advent Calendar 2016 : 農夫 山羊 キャベツ 狼 - Qiita です。偶然ですが同じ方が執筆担当ですね。 さて、本エントリでは Haskell の型の表現力をよ…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2016/12/19/060147</id><title type="text">NGK2016B で Kubernetes + Alloy について話してきました</title><updated>2016-12-19T06:01:47+09:00</updated><author><name>チェシャ猫</name></author><link href="https://ccvanishing.hateblo.jp/entry/2016/12/19/060147"/><summary type="html">先日、毎年恒例のなごや LT 大会 NGK2016B / 名古屋合同懇親会 2016 忘年会 で発表してきました。 机上の Kubernetes - 形式手法で見るコンテナオーケストレーション #NGK2016B from y_taka_23 www.slideshare.net 当日の動画は NGK 2016B LT #2 - YouTube から見ることができます。 ちなみに NGK での発表は 4 年連続 4 回目です。今回も含めてすべてモデル検査が題材になっています。 NGK2013B : Alloy ではじめる簡単モデル検査 NGK2014B : 猫でもわかる！ モデル検査器 SPI…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2016/12/18/181540</id><title type="text">波打たせるものの正体(エクステンシブル・タングル)</title><updated>2016-12-18T18:15:40+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2016/12/18/181540"/><summary type="html">Haskell Advent Calendar 11日目 リアルワールドなHaskellerは、幾十ものフィールドを持つ大きなレコードをしばしば扱う羽目になる。モナディックにレコードを構築したい場合、RecordWildCards拡張を用いて以下のようにするのが定番だ。 import System.Random data Rec = Rec { foo :: String, bar :: Int, baz :: Double, qux :: Bool } makeRec = do foo &lt;- getLine bar &lt;- length &lt;$&gt; getLine baz &lt;- readLn qu…</summary></entry><entry><id>https://kurokawh.blogspot.com/2016/12/haskellyesod-typedcontent.html</id><title type="text">[haskell][yesod] TypedContentを利用してクライアントが要求するフォーマットでレスポンスを返す</title><updated>2016-12-17T15:16:26.835+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2016/12/haskellyesod-typedcontent.html"/><summary type="text">Yesod Advent Calendar 2016の6日目の記事です。

RESTfulなAPIを提供する場合、クライアントの都合にあわせて、フォーマットを変えてレスポンスを返したいケースがあります。サーバー上で管理しているDBから、表現だけをHTML, JSON, XML, CSVなどに変更して返すイメージです。例えば、人物情報（名前、年齢、性別など）の一覧を返す際には以下のようなデータが返されることになります。

HTML
&lt;table border&gt;
  &lt;tr&gt;
    &lt;th&gt;name&lt;/th&gt;    &lt;th&gt;sex&lt;/th&gt;    &lt;th&gt;age&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Taro Yamada&lt;/td&gt;    &lt;td&gt;Male&lt;/td&gt;    &lt;td&gt;18&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Hanako Yamada&lt;/</summary></entry><entry><id>https://kurokawh.blogspot.com/2016/07/yesodhaskell-stack-new-xxx-project.html</id><title type="text">[haskell][yesod] stackのnewコマンドで指定できるyesod関連templateの説明</title><updated>2016-12-03T23:37:28.283+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2016/07/yesodhaskell-stack-new-xxx-project.html"/><summary type="text">現状、stackで指定できるyesod関連のtemplatesには以下のものがあります。どのtemplateに何が用意されているのか、知りたかったのですがどこにも説明されていないようなので、調べてまとめてみました。
% stack templates | grep yesod
yesod-hello-world （←現時点では削除されています）
yesod-minimal
yesod-mongo
yesod-mysql
yesod-postgres
yesod-postgres-fay
yesod-simple
yesod-sqlite


以下、各テンプレートの説明です。後に出てくるテンプレートほど内容が複雑になっています。テンプレートを指定して新しいプロジェクトを生成する場合は以下のコマンドを実行します。
% stack new プロジェクト名 yesod-???




</summary></entry><entry><id>https://kurokawh.blogspot.com/2016/11/emacs-emacsgrep.html</id><title type="text">[emacs] emacs上のgrep関連機能、複数ファイルの一括置換手順のまとめ</title><updated>2016-11-30T10:03:25.873+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2016/11/emacs-emacsgrep.html"/><summary type="text">emacs上でgrep関連の機能を利用する際のTIPSをまとめておきます（よく忘れて調べ直すので…）。


grepコマンドのオプション

指定ディレクトリ以下のファイルを再帰的に検索

-R DIR    シンボリックリンクを辿る
-r  DIR    シンボリックリンクは辿らない

検索対象をファイル名でフィルタする

--include=GLOB    GLOBにファイル名を指定する。"*.cpp"のようにワイルドカード（*,?,[...]）を指定可能

検索対象から指定ファイル・ディレクトリを除外する

--exclude=GLOB   GLOBに除外するファイルのファイル名を指定する（ワイルドカード指定可能）。
--exclude-dir=DIR DIRに指定されたディレクトリをスキップ


使用例：

docディレクトリ以下の.txtを拡張子に持つ全てのファイルを対象に"</summary></entry><entry><id>https://kurokawh.blogspot.com/2016/09/cygwin-cygwin64.html</id><title type="text">[cygwin] cygwin64セットアップメモ</title><updated>2016-11-28T00:47:36.358+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2016/09/cygwin-cygwin64.html"/><summary type="text">自分向け備忘録。cygwin64環境をセットアップする際の手順をまとめておきます。


設定


ssh-agent関連

ssh-agentの重複起動を防ぐ
ssh-agentのために秘密鍵セットアップ

~/.ssh/

※group/otherのrw権限は削除


ssh-agentがパスワードを覚えてくれなくなった問題への対処

pingのエラー回避
ユーザーのアカウント名、ホームディレクトリの変更

/etc/passwdを編集する

GNU screen でlessやvimの終了後に画面クリアをしない方法
改行コードにCR+LFが用いられているbashスクリプトを実行するための設定
tcshのデフォルト補完設定のイマイチな部分を修正




環境変数

HOME

ホームディレクトリを設定



SHELL

"/bin/tcsh"とすることでデフォルトのシェルが切り替わる
</summary></entry><entry><id>http://syocy.hatenablog.com/entry/2016/10/31/025512</id><title type="text">HaskellのロガーKatipを試す</title><updated>2016-10-31T02:55:12+09:00</updated><author><name>syocy</name></author><link href="http://syocy.hatenablog.com/entry/2016/10/31/025512"/><summary type="html">モチベ Haskell の実行時ログ出力を行うライブラリは monad-logger が一番有名っぽい。 これは Yesod 陣営が開発しているから安心感があるし、バックエンドが fast-logger なので速度も信頼できる。 ただ (自分の調べ方が悪いのかもしれないが) ちょっと自分の用途には機能が足りなかった。 具体的には以下の機能: ログにタイムスタンプを付記したい。 ロガーに名前をつけたい。 ファイルサイズか日付でログローテーションしたい。 Katip という別のロガーライブラリは機能が豊富のようなので今回はそれを試してみる。 (この記事のHaskell環境: lts-6.23) K…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2016/10/10/000011</id><title type="text">割とすぐに始められるextensibleチュートリアル(レコード編)</title><updated>2016-10-10T00:50:06+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2016/10/10/000011"/><summary type="html">ごきげんよう諸君。今回はextensibleについて説明しよう。 extensibleはその名の通り、拡張可能なデータ構造を提供するライブラリである。具体的には、型レベルのリストによって特徴づけられる積と和を提供する。非常に残念なことに、GHC 8.0.1ではコンパイラのバグのせいでそもそもライブラリがビルドできない*1。来たる8.0.2では修正されているので、それを待つほかない。 とにかく、ここでは積の応用技である拡張可能レコードについて紹介する。使い方は簡単だ。まず使いたいフィールド名をスペースで区切ってmkFieldに渡す。 {-# LANGUAGE TemplateHaskell, D…</summary></entry><entry><id>https://kurokawh.blogspot.com/2016/08/haskellyesod-yesodrestfuljson-api.html</id><title type="text">[haskell][yesod] YesodにおけるRESTfulなJSON API実装チュートリアル</title><updated>2016-08-28T17:53:43.356+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2016/08/haskellyesod-yesodrestfuljson-api.html"/><summary type="text">HaskellのwebフレームワークであるYesodにおいて、RESTful APIを実装する手順を紹介します。Haskell上のデータ構造をJSONテキストに変換する、逆に、JSONテキストをパースしてHaskell上のデータ構造を生成する、といった処理が非常に簡単に実現できます。加えて、コードを書かなくてもバックエンドのDBとのORマッピングが可能になっており、効率的に開発することができます。
ここで紹介しているコードはgithubにコミットしています。


準備：

json-sampleというプロジェクト名でYesodのscaffolding siteをセットアップする

空のプロジェクト生成

% stack new json-sample yesod-sqlite --system-ghc

"--system-ghc"は省略可能。インストール済みのghcを使うことを指示し</summary></entry><entry><id>https://kurokawh.blogspot.com/2016/07/haskellyesod-stackyesod-tutorial.html</id><title type="text">[haskell][yesod] stack対応版Yesod tutorial</title><updated>2016-07-17T18:06:36.108+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2016/07/haskellyesod-stackyesod-tutorial.html"/><summary type="text">HaskellのwebサービスフレームワークにYesodというフレームワークがあります。Yesodに触れたことのない開発者向けに書かれたチュートリアルの一つにYesod tutorialがあり、手順に沿っていくだけで簡単なwebサービスを動作させることができ、Yesodで何ができるかを簡単に理解できるようになっています。
ただ残念なことに、このYesod tutorialの記載は内容が古く、stackを利用した現行の手順とマッチしなくなっています。stackに対応している最新環境（Yesod 1.4.x）における順があると役に立つと思い、書き起こしてみました。


Before the real start（はじめに）

Install（インストール手順）
stackをインストールする。以下のサイトが参考になります。

installation instructions for </summary></entry><entry><id>https://kurokawh.blogspot.com/2016/07/haskellyesod-stack-exec-yesod-devel.html</id><title type="text">[haskell][yesod] stack exec -- yesod devel で devel.hs: getAddrInfo: does not existというエラーになる問題の対処方法</title><updated>2016-07-17T17:39:43.279+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2016/07/haskellyesod-stack-exec-yesod-devel.html"/><summary type="text">
Widnwos環境での現象：
windows上でyesodのscafolding siteをセットアップし、さあ起動！ブラウザから接続確認してOKとなるはずが、なぜか「The application isn't built」という表示が出てしまいました。



このときターミナルには以下のようなログが出力されていました。
% stack exec -- yesod devel
Yesod devel server. Type 'quit' to quit
Application can be accessed at:

http://localhost:3000
https://localhost:3443
If you wish to test https capabilities, you should set the following variable:
  export </summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2016/05/03/211430</id><title type="text">写真の撮り方</title><updated>2016-06-14T23:59:05+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2016/05/03/211430"/><summary type="html">物体の発する光や反射した光を結像し、何らかの媒体に記録したものを写真と呼ぶ。カメラと呼ばれる道具には「撮影」という動作が必ず定義されており、撮影によって内部状態に画像を記録できる。内部状態を取り出して処理する(現像)ことで写真が得られる。大抵のカメラには以下のようなパラメータがあり、それらを最適化するのが撮影者の仕事になる。 焦点(Focus) はっきりとした像を得るには、光学系の焦点をそれに合わせる必要がある。最近のカメラは対象物の距離を測定し、自動で焦点を合わせる(オートフォーカス)機能を持っているものもある。 焦点距離(Focal length) 焦点距離が長いほど像は拡大されて見えるよ…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2016/04/08/215045</id><title type="text">今のところ比較的簡単なモナドの作り方</title><updated>2016-04-08T21:51:50+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2016/04/08/215045"/><summary type="html">準備 モナドを作るには、どんなモナドを作りたいか考える。モナドは一般に、どのようなアクションが使えるかによって特徴付けられる。その点ではオブジェクト指向におけるインターフェイスとよく似ている。 では、foo :: String -&gt; M Boolとbar :: M Intという二種類のアクションを持つモナドを作るとしよう。まず、どんなアクションが使えるかを表すデータ型を定義する。 {-# LANGUAGE GADTs #-} data MBase x where Foo :: String -&gt; MBase Bool Bar :: MBase Int GADT(一般化代数的データ型)の各データ…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2016/02/29/191740</id><title type="text">GHC 8.0.1/base-4.9.0.0の新機能まとめ</title><updated>2016-02-29T19:17:40+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2016/02/29/191740"/><summary type="html">GHC 8.0.1は、最上位の桁が変わるだけあって、かなり新しい機能が追加されている。 base-4.9.0.0 めっちゃインスタンスが増えた ghc/changelog.md at ghc-8.0 · ghc/ghc · GitHubを参照。あるべきインスタンスが存在することにより、孤児インスタンスを定義する必要がなくなるため、ぐっとストレスが減る。Monoid a =&gt; Monad ((,) a)、Traversable ZipListなど、いくつかは私がやった。 Semigroup ついにData.Semigroupが追加された。将来的にはこれはモノイドのスーパークラスになる。この変更に…</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2016/02/04/214714</id><title type="text">比を最適化する</title><updated>2016-02-04T21:47:14+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2016/02/04/214714"/><summary type="html">二つの負でない実数、を考える。比をある値に近づけたいといった条件が複数あり、それらを最適化したいとき、どうするのがよいだろうか。 序: 近道の階段 簡単な方法の一つとして考えられるのは、単純に比の差をとり、それらの平方の和を最適化の対象とするというものだ。 しかし、これは最適化の結果、しばしば、のどちらかが0にぶつかってしまう。これは目的関数として非常にいびつであり、直感的とも言いがたい。 破: バリアフリー化 0や1に近い比率は極端であり、望まれていない。境界に近づくほど目的関数が無限大に発散するようにできないだろうか。 そんなときに使えるのがロジットだ。ロジットは0より大きい1未満の実数を…</summary></entry><entry><id>https://kurokawh.blogspot.com/2015/11/haskellyesodsqlite-persistent.html</id><title type="text">[haskell][persistent][sqlite] Persistentパッケージ利用時にテーブルにインデックスを生成する方法</title><updated>2016-01-30T17:12:12.076+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2015/11/haskellyesodsqlite-persistent.html"/><summary type="text">PersistentパッケージにはMigration機能が備わっており、自動的にテーブルを生成してくれます。スキーマ変更を行った際にも、変換が可能な限りテーブル内のレコードを保持したまま新しいスキーマに変換してくれます（Migration機能については過去のエントリでまとめています）。

自分が利用する上で、インデックスやトリガーを生成する手順が紹介されておらず困っていたのですが、rawExecuteという関数を用いることで自由にDDLを発行できることがわかりました。以下その手順とサンプルを紹介しておきます。


サンプルコード：
以下は、personテーブルのnameカラムにインデックスをs生成するサンプルです。runMigration実行直後に、runExecuteを実行することでインデックスを生成しています。このサンプルではインデックスを生成しているだけですが、同じ手順でトリガーの</summary></entry><entry><id>https://kurokawh.blogspot.com/2015/08/haskellyesodsqlite-persistentmigration.html</id><title type="text">[haskell][persistent][sqlite] Persistentパッケージのmigration機能のまとめ</title><updated>2016-01-30T17:11:40.032+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2015/08/haskellyesodsqlite-persistentmigration.html"/><summary type="text">HaskellでDB操作ができるPersistentパッケージの紹介をしましたが、このエントリではPersistentパッケージが提供しているmigration機能をまとめておきます。
DBを作って運用していると、機能追加や仕様変更に伴いスキーマ変更が必要になるケースが多々あります。このようなケースにおいてPersistentのmigration機能がどれくらい使えるのかを調べた結果です。


基本：
Persistetのmigration機構は（保守的なルールに沿って）スキーマ変更をある程度まで自動で処理してくれます。
ロードしたDB内のテーブル情報と、コードで定義されたEntity Definition（テーブル定義）を比較し、以下のケースにおいてスキーマの変更を行います。

カラムの型を変更した場合：

ただし、値の変換ができない場合には、DBによって拒否されることになります。

</summary></entry><entry><id>https://kurokawh.blogspot.com/2016/01/haskellgccwin-windowshaskell.html</id><title type="text">[haskell][gcc][win] Windows版Haskell Platform付属のgccでC++11のコードをコンパイルする方法</title><updated>2016-01-15T00:45:37.692+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2016/01/haskellgccwin-windowshaskell.html"/><summary type="text">Windows版のHaskell Platformにはmingwが同梱されておりgccが含まれています。現在自分のPCにはHaskell Platform 2014.2.0.0をインストールしているのですが、これに付属されているgccでC++11のコードをコンパイルしようとすると、以下のようなエラーになってしまいました。
% gcc -std=c++11 cpp11.cpp
cc1plus.exe: error: unrecognized command line option '-std=c++11'


-stdオプションで"c++11"を指定しても、認識してくれません。
本家のサイトによると、'-std=c++11'オプションはgcc 4.7でサポートされたようです。これに対し、Haskell Platform 2014.2.0.0に付属されているgccのバージョンを確認したところ</summary></entry><entry><id>https://kurokawh.blogspot.com/2013/11/sqlite-sqlite.html</id><title type="text">[sqlite] SQLiteのロック・トランザクション関連仕様の整理</title><updated>2016-01-06T12:11:40.986+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2013/11/sqlite-sqlite.html"/><summary type="text">SQLiteは共有ロック・排他ロックの仕組みを備えており、プロセス内の複数スレッド、だけでなく、プロセスをまたぐ状態でSQLが同時に発行されても適切に処理されます。
トランザクションに複数のモードが存在し、指定するモードに依って取得されるロックが変わります。さらにSQLの内容に依存してロック状態が遷移するため、複数プロセスがアクセスしたときの挙動を正確に把握できるよう、仕様を整理してみました。
（文中の「プロセス」は、正確には「プロセス、もしくはスレッド」を意味します。）


DBのロック状態の種類：

UNLOCKED

ロックされていない状態。誰も読み書きしていない。DBの初期状態。

SHARED

read可、write不可な状態。複数プロセスが同時にSHAREDロックを取得可能。複数プロセスが同時にreadできることを意味する。DBがこの状態にあるとき、他のプロセスからの</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2015/12/30/220159</id><title type="text">デシリアライザとスキーマ</title><updated>2015-12-30T22:16:49+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2015/12/30/220159"/><summary type="html">盛大に遅れました… qiita.com 最近思いついたネタで実用性の高そうなものを紹介。 binaryやcerealのようなライブラリはデータを密にシリアライズするが、その際にフィールド名や型などの情報は失われてしまう。かといってそれらを一つ一つすべて含めるとひどく効率の悪いフォーマットになってしまう。そこで、スキーマを分離できるような仕組みを作れないかと考えて作ったのがこのクラスだ。 {-# LANGUAGE TypeFamilies, ScopedTypeVariables, FlexibleContexts, UndecidableInstances #-} import Data.Bi…</summary></entry><entry><id>https://kurokawh.blogspot.com/2015/07/cygwinhaskellemacs-mingwcygwincygdrivec.html</id><title type="text">[cygwin][haskell][emacs] MinGWでcygwinの"/cygdrive"パスにアクセスする裏技（cygwin環境のemacsでflycheckを動作させる方法）</title><updated>2015-12-27T23:55:24.842+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2015/07/cygwinhaskellemacs-mingwcygwincygdrivec.html"/><summary type="text">haskell関連のコマンドはMinGW上でビルドされているため、cygwin環境の"/cygdrive"から始まるパスには対応していません。haskell-hlintから呼び出されるhlintも当然この問題の影響を受けておりemacs関連の設定が適切にされていたとしても、以下のようなエラーが表示されてしまいます。



ミニバッファに表示されるエラー詳細：
Suspicious state from syntax checker haskell-hlint: Checker haskell-hlint returned non-zero exit code 1, but no errors from output: hlint.exe: Couldn't find file: /cygdrive/c/Users/Hiroyuki/tmp/flycheck_hello.hs



</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2015/12/10/200630</id><title type="text">正格フラグ、バンパターン、正格版関数・データ構造</title><updated>2015-12-10T20:06:30+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2015/12/10/200630"/><summary type="html">Haskellスペースリーク Advent Calendar 2015 9日目 Haskellerとて、時には厳しくならなければいけないこともある―― @fumieval, 2015 Haskellは遅延評価を基本としているため、場合によっては未評価の式が積もり非効率な状況に陥ることがある。これを防ぐため、部分的に正格評価にするための仕組みが用意されている。もちろんこれらは闇雲に使えばよいというものではない。使うべきポイントを把握し、これらを見逃さないようにしよう。 この記事では、それらの機能の正しい使い方、間違った使い方を紹介していこう。 カウンター・カウンターズ・サンクス 条件を満たす要素…</summary></entry><entry><id>https://kurokawh.blogspot.com/2015/11/haskellstack-stack-exec-ghcicouldnt.html</id><title type="text">[haskell][stack] stack exec ghciで”Couldn't match expected type"エラーが発生する問題の対処</title><updated>2015-11-08T15:09:21.187+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2015/11/haskellstack-stack-exec-ghcicouldnt.html"/><summary type="text">先日、haskellのパッケージ管理をcabalからstackに移行して「便利〜！」と感動していたところなのですが、stach exec ghciでソースをロードしようとすると"Couldn't match expected type: xxxxx"とエラーが発生する問題に遭遇しました。
ネットの情報を参考に解決することができたのでその手順をまとめておきます。


問題：
stack buildは成功するにもかかわらず、stack exec ghci xxx.hs（xxx.hsはbuild対象のファイル）がエラーになる。
stack exec ghci実行時のエラーログ：
% stack exec ghci FileToVec.hs
GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
[1 of 1] </summary></entry><entry><id>https://kurokawh.blogspot.com/2015/11/cygwin-cygwinpathusrbinusrlocalbin.html</id><title type="text">[cygwin] cygwinのシェル起動時にPATHの先頭に/usr/binと/usr/local/binが勝手に追加されないようにする</title><updated>2015-11-04T22:29:43.126+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2015/11/cygwin-cygwinpathusrbinusrlocalbin.html"/><summary type="text">cygwinのデフォルトの設定では、シェル起動時に以下の2つのディレクトリが自動的にPATHの先頭に追加されます。

/usr/local/bin
/usr/bin


cygwinでインストールされているコマンドと同名の別コマンドを優先して起動したい場合には、この設定が邪魔になります。
これを無効にするには以下の方法があります。お好みでどちらかを選択してください。

/etc/profileもしくは/etc/csh.loginの該当処理をコメントアウトする（bash / tcsh）

cygwinがPATHを上書きしているのは、/etc/profile（bashの場合）と/etc/csh.login（tcshの場合）です。これらのスクリプトを編集することで、/usr/binと/usr/local/binが勝手に追加されないようにできます。

ORIGINAL_PATHでPATHを上書き</summary></entry><entry><id>http://fumieval.hatenablog.com/entry/2015/10/27/234832</id><title type="text">動物、とくにヒトと性について</title><updated>2015-10-27T23:52:44+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="http://fumieval.hatenablog.com/entry/2015/10/27/234832"/><summary type="html">我々脊椎動物は有性生殖をする。したがって、繁殖に寄与する性質が必然的に残り、そうでないものは消えてゆく。オスは精子、メスは卵を作り出すという非対称性があり、体つきや行動もそれに合わせるように決まるのは自然だ。一夫多妻制の種においては、オスはメスを取り合うためにより強靭で攻撃的な性質が要求される。日本では法律上一夫一妻制を取るが、その影響は強く残っているだろう。実際、オスとして生を受けた私も、コミュニティの中でそれを体感している。 生まれつきの体質か、育った環境のせいかは知らないが、幼いころは体が弱かった(3才のころ、両足飛びができなかったそうだ)。そのため、幼いころの私の趣味は読書、ままごとや…</summary></entry><entry><id>https://kurokawh.blogspot.com/2015/09/ssh-opensshssh-agent.html</id><title type="text">[ssh] OpenSSHのアップデートでssh-agentがパスワードを覚えてくれなくなった問題への対処</title><updated>2015-09-06T00:44:24.703+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2015/09/ssh-opensshssh-agent.html"/><summary type="text">ssh-agent/ssh-addを利用してsshを用いたサーバーへのログイン時のパスワード入力を省略している方、OpenSSHのアップデートにより、毎回パスワード入力を求められるようになった場合は以下の設定を疑ってみてください。


問題の症状：
OpenSSHパッケージを最新版にアップデートすると発生するようになった問題です。ssh-agentを起動してssh-addで鍵を正しく登録しているにも関わらず、sshコマンドを実行する度に"password:"というプロンプトが表示されてパスワードの入力を求められてしまいます。


環境：
問題に遭遇＆解決した私のcygwin環境では以下のバージョンで問題が発生することを確認しました。

OpenSSH_7.0p1, OpenSSL 1.0.2d 9 Jul 2015
OpenSSH_7.1p1, OpenSSL 1.0.2d 9 Jul </summary></entry><entry><id>https://kurokawh.blogspot.com/2015/09/cygwin-cygwinx-serverxwin.html</id><title type="text">[cygwin] cygwin版X server（XWin）にリモートクライアントから接続できない問題の対処方法</title><updated>2015-09-02T23:09:07.989+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2015/09/cygwin-cygwinx-serverxwin.html"/><summary type="text">cygwinを最新バージョンにアップデートしたところ、リモートのX clientからwindows上のcygwin版X serverに接続できなくなってしまいました。
対処方法は簡単でXWin起動時に"-listen tcp"オプションを付けてあげればよいだけです。cygwinバージョンアップ前にはオプション指定なしで接続できていたため、デフォルトの設定が変わったのだと思われます。


cygwin環境：
uname -aで表示されるcygwinバージョン情報です。

% uname -a
CYGWIN_NT-6.1 xxx 2.2.1(0.289/5/3) 2015-08-20 11:42 x86_64 Cygwin



問題発生時の症状：
クライアント側で起動したxtermをサーバー側で表示しようとすると、以下のようなエラーになっていました。
% xterm
xterm Xt </summary></entry><entry><id>https://kurokawh.blogspot.com/2015/08/cygwinemacs-cygwinemacsgtags.html</id><title type="text">[cygwin][emacs] cygwin版emacsでgtagsを使えるようにする方法</title><updated>2015-08-17T00:49:02.649+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2015/08/cygwinemacs-cygwinemacsgtags.html"/><summary type="text">これまでタグジャンプにはctagsを用いていたのですが、gtagsの「呼び出し元も一覧できる」という機能に惹かれてセットアップしてみました。いくつかはまりポイントがあったのでその対応方法も含め、手順を残しておきます。
cgwin提供のパッケージにはgtagsは含まれていなかったため、自前でビルドすることにしました。


目次：

gatgsの特徴
gtagsのインストール手順
emacsの設定
gtagsの使い方




gtagsの特徴：

良い点！

関数の呼び出し元を一覧表示しジャンプできる（gtags-find-rtag）
関数だけでなく、ローカル変数を含む任意のシンボルをタグジャンプできる（gtags-find-symbol）

正規表現で一覧絞り込み可能（gtags-find-pattern）
開いているファイルで絞り込み可能（gtags-parsefiile）

特定文字列</summary></entry><entry><id>http://lotz84.github.io/posts/published_haskell_by_example.html</id><title type="text">Haskell by Exampleを公開しました</title><updated>2015-05-06T00:00:00Z</updated><author><name>lotz</name></author><link href="http://lotz84.github.io/posts/published_haskell_by_example.html"/><summary type="html"></summary></entry><entry><id>http://lotz84.github.io/posts/build-chat-server-on-haskell.html</id><title type="text">Haskellでチャットサーバーを建ててみた</title><updated>2015-04-27T00:00:00Z</updated><author><name>lotz</name></author><link href="http://lotz84.github.io/posts/build-chat-server-on-haskell.html"/><summary type="html"></summary></entry><entry><id>http://lotz84.github.io/posts/unity-hands-on-session-at-camphor.html</id><title type="text">Unityハンズオン勉強会に参加しました@CAMPHOR-</title><updated>2015-04-25T00:00:00Z</updated><author><name>lotz</name></author><link href="http://lotz84.github.io/posts/unity-hands-on-session-at-camphor.html"/><summary type="html"></summary></entry><entry><id>http://lotz84.github.io/posts/the-way-of-separate-compilation-in-swift.html</id><title type="text">Swift で分割コンパイルする方法</title><updated>2015-02-07T00:00:00Z</updated><author><name>lotz</name></author><link href="http://lotz84.github.io/posts/the-way-of-separate-compilation-in-swift.html"/><summary type="html"></summary></entry><entry><id>http://lotz84.github.io/posts/use-selenium-by-haskell.html</id><title type="text">HaskellでSeleniumを使ってみる＠勉強会</title><updated>2014-12-14T00:00:00Z</updated><author><name>lotz</name></author><link href="http://lotz84.github.io/posts/use-selenium-by-haskell.html"/><summary type="html"></summary></entry></feed>