<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Haskell Antenna</title><id>https://haskell.jp/antenna/feed.xml</id><updated>2026-04-19T21:08:38+09:00</updated><link href="https://haskell.jp/antenna"/><entry><id>https://qiita.com/TThaskboy/items/820e05371dba4d0b8902</id><title type="text">HaskellでABC454を解く</title><updated>2026-04-19T21:08:38+09:00</updated><author><name>Qiita</name></author><link href="https://qiita.com/TThaskboy/items/820e05371dba4d0b8902"/></entry><entry><id>https://qiita.com/TThaskboy/items/e9964bd6a6c4c993e674</id><title type="text">HaskellでABC453を解く</title><updated>2026-04-12T14:24:41+09:00</updated><author><name>Qiita</name></author><link href="https://qiita.com/TThaskboy/items/e9964bd6a6c4c993e674"/></entry><entry><id>https://qiita.com/K_san0219/items/f716ef7e345b22953bef</id><title type="text">Haskellのモナドを何が何でも理解する（Pythonでもわかる）</title><updated>2026-04-11T15:30:34+09:00</updated><author><name>Qiita</name></author><link href="https://qiita.com/K_san0219/items/f716ef7e345b22953bef"/></entry><entry><id>https://qiita.com/ohikouta/items/f9d28535fe7e35c39c74</id><title type="text">Haskell の数値計算ライブラリで logSumExp の実装を読む</title><updated>2026-04-08T22:40:09+09:00</updated><author><name>Qiita</name></author><link href="https://qiita.com/ohikouta/items/f9d28535fe7e35c39c74"/></entry><entry><id>https://zenn.dev/38koo/articles/693d2b8e8a1684</id><title type="text">AIはアウトプットだけじゃない。学習ツールとして使ってみた。</title><updated>2026-03-22T09:11:25+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/38koo/articles/693d2b8e8a1684"/><summary type="html">日々、AIの進化が目覚ましく、実務で使わない日はないほどになってきました。
アウトプットへのハードルは劇的に下がった一方、私自身はインプット目的でAIを活用することも多くあります。壁打ち相手として使ったり、技術的にわからない箇所を深掘りしたり……。
そこで今回は、AIを用いたインプットがどれほど学習に効果的かを検証すべく、Haskellを題材にミニマムなCLIアプリケーションを作ってみます。

 目的
AIを用いたインプットが学習に有効かどうかを、実際に手を動かして実感する。

 やること
ミニマムなCLI Todoアプリケーションの作成
今回の目的はインプットが行えるかを検証したいので...</summary></entry><entry><id>https://kurokawh.blogspot.com/2023/02/windows-windows11.html</id><title type="text">[windows] Windows11セットアップ・設定項目のメモ</title><updated>2026-03-19T11:33:37.642+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2023/02/windows-windows11.html"/><summary type="text">スタートメニュー・タスクバーの設定個人用設定 ＞ タスク バータスクバー項目検索： 「非表示」タスクビュー： オフウィジェット： オフタスクバーの動作タスクバーの配置：　左揃えタスクバーをすべてのディスプレイに表示する：　アンチェック（拡張ディスプレイ接続状態で設定）タスクバーのボタンをまとめラベルを非表示にする：　常時タスクバーのボタンをまとめほかのタスクバーでラベルを非表示にする：常時タスクバーボタンを表示する：　タスクバーに入りきらない場合スタートメニューにコントロールパネルを表示する「Windows 10」のコントロールパネルを表示する方法についてスタートメニューにピン止めするアプリ：（下記以外は「スタートからピン留めをはずす」）WindowsシステムツールコントロールパネルWindowsアクセサリペイントパワーポイントエクセルAcrobat </summary></entry><entry><id>https://zenn.dev/unmummied/articles/20260319000000</id><title type="text">証明: Applicative の合成は Applicative</title><updated>2026-03-18T15:00:11+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/unmummied/articles/20260319000000"/><summary type="html">初投稿です.
Data.Functor.Compose には次のような説明があります.

The composition of applicative functors is always applicative, but the composition of monads is not always a monad.

Applicative が合成について閉じているという性質によって, Applicative では汎用的な合成型が書けます. それがこの Data.Functor.Compose です.

 Defined in Data.Functor.Compose
newtype...</summary></entry><entry><id>https://zenn.dev/ikaro1192/articles/ba0105a3d605b8</id><title type="text">MySQL 8.4対応のシンプルなHA管理ツールをHaskellで自作した話</title><updated>2026-03-18T11:03:38+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/ikaro1192/articles/ba0105a3d605b8"/><summary type="html">
 要約
MySQL 8.4対応のシンプルなHA管理ツールPureMyHAをHaskellで作成しOSSとして公開しました。
MySQL 8.4の非同期レプリケーション/準同期レプリケーション環境にて自動フェイルオーバーや手動スイッチオーバーが可能となります。
https://github.com/ikaro1192/PureMyHA
本ツールの作成にはClaude Codeを利用しました。
本記事ではそちらの体験やHaskellを採用した理由などについて説明しています。

 はじめに：なぜ今、HA管理ツールを自作したのか
現代のデータベース運用において、Amazon Aurora等のマ...</summary></entry><entry><id>https://zenn.dev/sigma_tom/articles/566e68f844cd4f</id><title type="text">Haskellのfoldl、foldl&#39;、foldrを比較してみた</title><updated>2026-03-16T03:36:51+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/sigma_tom/articles/566e68f844cd4f"/><summary type="html">
 これは何?
(この記事はクロス投稿です)
Haskellの畳み込み関数の3つの使い分けについて解説する。
この記事を読み、以下がわかるようになれば幸いである。


foldlは巨大サンクを作るため使うべきでない

foldl&#39;は厳密な左畳み込みであるため、パフォーマンスが良くなる

foldrは演算子が正格でないなら遅延評価の強みが活かせる



 foldlは巨大なサンクを作ってしまう。
最後の要素以外のすべてを結合した結果を、最後の要素と再帰的に結合する方法[1]をfoldl(末尾再帰)と呼ぶ。
foldlを利用してリストの合計を求める例を使ってfoldlの弱点を説明する。
gh...</summary></entry><entry><id>https://zenn.dev/ml/articles/fdc3a0734070d1</id><title type="text">PythonのrequestsっぽいHTTPクライアントをHaskellで作った</title><updated>2026-03-14T11:23:59+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/ml/articles/fdc3a0734070d1"/><summary type="html">
 Haskellを学ぶときの悩み
Haskellを勉強し始めたころ、ずっと困っていたことがあった。「これ、どこで使うの?」という感覚が抜けなくて、なかなか前に進めなかった。
ある時、こんな仕事が入ってきた。HTTP APIからデータを取得して、ちょっと加工して、別のエンドポイントにPOSTする、というやつ。よくある感じの作業だ。いつもならPythonとrequestsライブラリで片付けるところ。URLを叩いてJSONを受け取って、変換して送る、それだけのことが数行で書ける。
でもふと思った。これ、Haskellでやってみるのにちょうどいい題材じゃないか。

 既存のライブラリを探してみ...</summary></entry><entry><id>https://zenn.dev/ok_xmonad/articles/dfae5e871539b0</id><title type="text">（仮）絶対できるHaskell 抄「圏論とファンクター」</title><updated>2026-03-06T09:23:40+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/ok_xmonad/articles/dfae5e871539b0"/><summary type="html">
 絶対できるHaskell抄
僕は、しばらく前から「（仮）絶対できるHaskell」という本をZennで書いているのですが、なかなか完成しません。
「Haskell初心者本」という目線で執筆しだしたのですが、執筆するために色々調べたり、考えたり、例示プログラムを書いているうちに、書き始めた頃よりも僕自身もHaskellの理解が進み、以前の説明の書き方に不満を覚え、書き直し、、、ということの繰り返しが起こっています。
最近は、「ファンクター」まわりの自習をしながら文章を書いてたのですが、このあたりの初学者目線の解説がほとんどみられないので、とりあえず、たたき台的なものですが、公開してみた...</summary></entry><entry><id>https://zenn.dev/aiya000/articles/93b397859c6fda</id><title type="text">【TypeScriptよりいいもの】未だ応用されきっていない、型システム本来の力の簡単紹介【読み物】</title><updated>2026-03-02T11:07:01+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/aiya000/articles/93b397859c6fda"/><summary type="html">
 これはなに？
型システム（静的型付けのシステム [1]）のオタクによる、ものすごく簡単な説明。
型システムには多くの機能が存在するため、必ずしも単純な強弱で語れないものの、基本的に上から下に行くほど、型システムがリッチになっていくことを意図している。

 C・C++
intやcharなどの値が区別できるが、いつの間にかそれぞれが紛れ込んでいたりする。

これは型チェックエラーにならない:
#include &amp;lt;iostream&amp;gt;

int main() {
  int age = 25;
  char grade = &#39;A&#39;;

  // intとcharには暗黙変換がある...</summary></entry><entry><id>https://kurokawh.blogspot.com/2018/01/cygwin-cygwin.html</id><title type="text">[cygwin] cygwinセットアップ・環境構築手順メモ</title><updated>2026-03-02T10:25:15.592+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する。





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

ssh-agentの重複起動を防ぐ


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



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

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



~/.ssh/


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

% chmod 700 ~/.ssh&amp;nbsp;


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

[linux][cygwin] less, manの終了直前の画面を</summary></entry><entry><id>https://zenn.dev/kuu/articles/20260222_functor</id><title type="text">HaskellのFunctorが圏論の関手であるというのはどういうこと？</title><updated>2026-02-22T14:20:14+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/kuu/articles/20260222_functor"/><summary type="html">最近圏論面白いと思っていて、人と話したり Gemini などに聞いたりしながら学んでいるので、その備忘録です。
一応 ChatGPT 及び Gemini に読んでもらっているのですが、浅学の身による理解なので間違ってるかもしれません。気になりましたらコメントお願いします。
また、この記事は Haskell をある程度触ったことがあることと高階関数とは何かを理解していることを前提として書いています。数学は前提としていないつもりですが分かりづらかったらすみません。

 fmap
Haskellには fmap と呼ばれる関数がある。以下のように定義されている。
class Functor f ...</summary></entry><entry><id>https://zenn.dev/4ergfbv547uezdf/articles/a3eb8a373f2b62</id><title type="text">含意(→)の用例：マンガ「数字であそぼ。」の論理パズルを解く</title><updated>2026-02-21T07:04:46+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/4ergfbv547uezdf/articles/a3eb8a373f2b62"/><summary type="html">
 背景
プログラマの飲み会で「含意っていう便利な論理記号があってぇ~」と宣ってみたは良いものの、全然うまく説明できなかったので書きました。

 含意(→)とは
and(&amp;amp;&amp;amp;)やor(||)やnot(!,~)はプログラマであれば良く使う論理記号かと思います。これらは古典論理と言われる分野の記号であり、その仲間がimply(→):含意です。含意は以下のような関係があります。
A → B  =  (not A) or B
日本語で言うと”Aならば必ずBである。Aでない場合Bがどうなっても知るか！”です。必要条件や十分条件の勉強をされた方はその話です(個人的には嫌いな体系。話を...</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2026/01/16/003718</id><title type="text">BuriKaigi 2026 で Lean によるコンパイラの証明について話してきました</title><updated>2026-01-16T00:37:18+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2026/01/16/003718"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された BuriKaigi 2026 で、定理証明支援系 Lean を用いたコンパイラの証明について登壇してきました。公募 CFP 枠です。 fortee.jp 講演概要 近年、生成 AI を利用したシステム開発はもはや特殊な選択肢ではなく、一般のプログラマでも十分に活用しうる水準の技術となりました。一方、生成 AI が高速かつ大量に、しかしハルシネーションを含んだ出力を行うことにより、その正しさを改めて確認する側の人間の負担感も様々な場所で聞かれ、AI Slop などと呼ばれています。ちなみに Slop とは「泥水」のことで、低品質な出力を例えた表現です…</summary></entry><entry><id>https://syocy.hatenablog.com/entry/2026/01/08/233100</id><title type="text">HaskellでGTK 4 tutorialを進めている</title><updated>2026-01-08T23:31:00+09:00</updated><author><name>syocy</name></author><link href="https://syocy.hatenablog.com/entry/2026/01/08/233100"/><summary type="html">GTK 4 tutorial という GTK についての充実したチュートリアルがある。(英語だが日本の方が作っているみたいだ。) toshiocp.github.io 何か GUI アプリケーションを作ってみたい気分だったので、冬休み自由研究としてこちらのサンプルコードを Haskell で書いてみるということをしていた。 Haskell で GTK アプリが書けるのかというと、haskell-gi という GTK のバインディングがある。これは単純に GTK の C API をラップするだけでなく、モダンな Haskell の開発体験ができるようによく考えられて作られているようだ。 gith…</summary></entry><entry><id>https://zenn.dev/koheiwada/articles/06a1edfa621ed4</id><title type="text">シェルで関数型プログラミング</title><updated>2026-01-08T15:44:25+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/koheiwada/articles/06a1edfa621ed4"/><summary type="html">以前、AWKを超えて：HaskellをUnixパイプラインに持ち込むという記事を書きました。Haskell でパイプライン処理を書く話です。
ただ、そもそものアイデアはこの記事の内容でした。ログを grep や awk で漁っていると、「これ、filter して map して fold してるだけだな」と気づいたのが始まりです。
シェルでの関数型プログラミングの基本は、改行区切りのテキストをリストとして捉えることです。
a
b
c
これを [&#34;a&#34;, &#34;b&#34;, &#34;c&#34;] と見なせば、あとは map, filter, fold を適用するだけです。
構造化ログや専用ツールがある時代ですが、...</summary></entry><entry><id>https://zenn.dev/zatsucat/articles/a643b971c623f3</id><title type="text">関数型プログラミングの疑問「副作用を起こさないプログラムなんてありえない」</title><updated>2025-12-29T01:01:01+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/zatsucat/articles/a643b971c623f3"/><summary type="html">関数型プログラミングについて全く知らなかった過去の自分の疑問に答えます。
関数型言語のプロからすると笑っちゃうような疑問だとは思いますが、なかなか初学者には答えにたどり着けませんでした。

 「Haskellはいいぞ」と言われても分からなかったあの頃
10年以上前の話だと思うんですが、プログラマーの師匠みたいな人に「Haskellいいぞ。主要言語にする必要はないけど、考え方は取り入れた方が良い」と言われて勉強しようとしたことはありました。
ただ、当時は入門書もそこまで多くなく、ネット記事も充実していなかったので、初学者の自分は良さがわからずに断念しました。
で、その時に文法の難しさとか以...</summary></entry><entry><id>https://blog.miz-ar.info/2025/12/my-contributions-to-ghc-2025/</id><title type="text">GHCへの私の貢献2025</title><updated>2025-12-28T12:53:38+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2025/12/my-contributions-to-ghc-2025/"/><summary type="html">私はここ数年、Haskellの主要な処理系であるGHCに趣味で貢献しています。この記事では、今年（2025年）行なった貢献を紹介します。バグ報告のみ（修正は他の人）のものも含みますが、その場合はその旨を書いています。 去 [&amp;#8230;]</summary></entry><entry><id>https://zenn.dev/anozon/articles/idiosyncratic-syntax-haskell</id><title type="text">各言語特有っぽい構文: Haskell</title><updated>2025-12-23T16:58:30+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/anozon/articles/idiosyncratic-syntax-haskell"/><summary type="html">この記事はプログラミング言語の特有構文 Advent Calendar 2025 14 日目の記事です。
個人的な好みを交えて紹介します。
二分探索のサンプルコード
言語の特徴をあえて使い実装している。
-- Haskell - ガード + パターンマッチ + モナド
import Data.Maybe (fromMaybe)

binarySearch :: Ord a =&amp;gt; [a] -&amp;gt; a -&amp;gt; Maybe Int
binarySearch arr target = go 0 (length arr - 1)
  where
    go left right
 ...</summary></entry><entry><id>https://zenn.dev/mozukichi/articles/cbfb9825768897</id><title type="text">HaskellとWin32 APIでウィンドウを表示する</title><updated>2025-12-23T15:00:04+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/mozukichi/articles/cbfb9825768897"/><summary type="html">これは「Haskell Advent Calendar 2025」24日目の記事です。
GHCのSystem.Win32モジュールを使うことでHaskellからWin32 APIを呼び出すことができます。このSystem.Win32モジュールを使って、簡単なウィンドウ表示を試します。

 単純なウィンドウ表示までの手順の全体像
HaskellでSystem.Win32を使ったウィンドウ表示を試す前に、単純なウィンドウ表示のプログラムをCで書いた場合の処理の流れをおさらいしておきます。処理の流れは以下のようになります。
#include &amp;lt;windows.h&amp;gt;

int WIN...</summary></entry><entry><id>https://zenn.dev/yvvakimoto/articles/a7c002500da603</id><title type="text">なぜ3次元回転はいろいろなのか：完全ガイドと実装tips</title><updated>2025-12-23T11:12:51+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/yvvakimoto/articles/a7c002500da603"/><summary type="html">
 概要
3次元回転はいろいろなやり方がある。回転行列に始まり、ロドリゲスの回転公式やらクォータニオンやら。なぜかくもややこしいのだろうか。この記事では3次元回転のややこしさに迫り、いろいろな手法を見通しよく統一的に導入する。アウトラインの描出を旨とし個別の概念の包括的な定義や説明、導出はしない。また各々の換算公式を逐一計算することはしないが、グレブナー基底を用いた導出方法や実用上の注意点、とくに角速度ベクトルとの関係についてはコメントする。最後にこうした同一概念の異なる表現をうまく扱う方法をJulia, Python, Haskellで紹介する。またアニメーションの作成方法についても添...</summary></entry><entry><id>https://zenn.dev/yoshikuni_jujo/articles/introduction-to-yaftee</id><title type="text">高階作用にも対応しconduitも使えるエフェクトシステムであるYafteeの紹介</title><updated>2025-12-22T08:46:34+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/yoshikuni_jujo/articles/introduction-to-yaftee"/><summary type="html">Haskell advent calendar 2025の23日目の記事です。

 はじめに
今年は高階作用にも対応しconduitも使えるエフェクトシステムであるYafteeを紹介します。
例題のコードはここ

 エフェクトシステムとは
端的に言うといろいろなモナドの機能を、ひとつのモナドのなかで使うやりかた。たとえば状態モナドと例外モナドの機能を両方使いたいとか。そのようなやりかたとしては古典的にはモナド変換子が使われていた。モナド変換子という仕組みではモナドの機能を積み重ねていく。使うモナドの機能が増えてくると層が多くなり見通しが悪くなる。lift . lift $ lift do...</summary></entry><entry><id>https://zenn.dev/hanao/articles/ad1d71765bd304</id><title type="text">HaskellでAtCoderやってたけどやっと茶色コーダーになれたので振り返り</title><updated>2025-12-21T08:49:10+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/hanao/articles/ad1d71765bd304"/><summary type="html">この記事はHaskell Advent Calender 2025の記事になります。

 なんの記事？
今年もAtCoderでHaskell頑張ったので1年間振り返りの記事です。

 2025年の成果
2年近くかかってやっと茶色になりました！とても長かった…
なんとか成長できたのでよかったことにします👍


 やってきたこと
今年やってきたことを振りかってみます

 AtCoder C埋め
まずは脱灰のために300以降のC埋めをしました。一部を除いてほとんど全て解いています。
https://kenkoooo.com/atcoder/#/table/flowert

 NoviSteps...</summary></entry><entry><id>https://zenn.dev/hand_accident/articles/6596ebc2528fdd</id><title type="text">FunctorチュートリアルとBiinvariant Opticsへの展望</title><updated>2025-12-17T11:24:45+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/hand_accident/articles/6596ebc2528fdd"/><summary type="html">
 はじめに/ロードマップ
関数型言語の一部にはモナドっていう、難しくて、人々が苦しんでて、わかった暁にはかならずチュートリアルを書きたくなるものがあるらしいですね。
この記事はモナドチュートリアルではありません。
個人的には難しいのってモナド自体というよりむしろ、仰々しい名前のついたフワッとした抽象、特に高階型まわりのあれやこれや、というジャンルだと思っています。
その代表例で、まだシンプルなやつであるFunctorというのがあります。
前半は、ゆっくりとFunctorのチュートリアルを行います。
だんだんギアをあげて隣接する概念に手を伸ばし、今アツい概念であるProfunctor O...</summary></entry><entry><id>https://zenn.dev/folio_sec/articles/06c4271b96bfb5</id><title type="text">ダンジョン生成に一様分布を求めるのは間違っているだろうか</title><updated>2025-12-16T23:29:21+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/folio_sec/articles/06c4271b96bfb5"/><summary type="html">これは FOLIO Advent Calendar 2025 17日目の記事です。

誰でも一度は魔王になって、勇者のくせになまいきだと、侵入者を撃退するためのダンジョン作りに興じたことがあるでしょう。ダンジョン（長いので以降は迷路と呼ぶ）は古くからある定番コンテンツなだけあって、自動的な生成アルゴリズムにも棒倒し法や穴掘り法など様々なものがあります。しかしアルゴリズムによっては長い直線だらけの通路ができてしまったり、反対に行き止まりが多くなってしまったりと生成される迷路に偏りが生じることも知られています。そこで本稿ではちょっと視点を加えて、特定のパターンに偏りがない完全に公平な迷路生成...</summary></entry><entry><id>https://zenn.dev/coconala/articles/c75fe112cc4d68</id><title type="text">TypeScript使いがHaskellに入門して、プログラミングパラダイムの「解像度」が上がった話</title><updated>2025-12-15T04:53:44+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/coconala/articles/c75fe112cc4d68"/><summary type="html">こんにちは、ココナラで Web エンジニアをしている慕狼ゆに (しのがみゆに) (@yuni_shinogami) です。
こちらは株式会社ココナラ Advent Calendar 2025 15 日目の記事です。

普段は業務で TypeScript を書いていますが、今回は技術的な How-to ではなく、「あえて Haskell に入門してみた」という個人の学習記録を書きたいと思います。
「なぜ今さら Haskell？」と思われるかもしれませんが、普段 TypeScript を書いている人間が、Haskell を学習することで、どのように普段使っている言語（JavaScript/T...</summary></entry><entry><id>https://zenn.dev/lotz/articles/93f73c17145819</id><title type="text">クロックパズルを単因子論で解く</title><updated>2025-12-11T22:47:16+00:00</updated><author><name>Zenn</name></author><link href="https://zenn.dev/lotz/articles/93f73c17145819"/><summary type="html">これは「Haskell Advent Calendar 2025」12日目の記事です。

タイトルにクロックパズルと銘打ちましたが、このパズルの本当の名前を私は知りません（知ってたら教えて下さい）。パズルというのは例えば、以下のように

左、中央、右にそれぞれ3時間と4時間と5時間を計る時計があり、時計の針は 1,2,3 を指しているとします。それぞれの押しボタンを押すと時計の針は以下のように動きます。

押しボタン a を押すと、左の時計の針が2時間進み、中央の時計の針が1時間進む
押しボタン b を押すと、中央の時計の針が2時間進み、右の時計の針が3時間進む
押しボタン c を押すと...</summary></entry><entry><id>https://haskell.jp/blog/posts/2025/wai-sample.html</id><title type="text">簡単なHaskellのみでServant並に高機能なライブラリーを作ろうとした振り返り</title><updated>2025-12-07T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/2025/wai-sample.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;hr /&gt;
&lt;p&gt;この記事は&lt;a href=&#34;https://qiita.com/advent-calendar/2025/haskell&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Advent Calendar 2025&lt;/span&gt;&lt;/a&gt;の&lt;span class=&#34;ascii&#34;&gt;7&lt;/span&gt;日目の記事です。&lt;/p&gt;
&lt;p&gt;本日は、「&lt;a href=&#34;https://www.youtube.com/playlist?list=PLRVf2pXOpAzJMFN810EWwGrH_qii7DKyn&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;製ウェブアプリケーションフレームワークを作る配信&lt;/a&gt;」で配信していた、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;製ウェブアプリケーションフレームワークを作るプロジェクトについて振り返ります。&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;のような型安全な&lt;span class=&#34;ascii&#34;&gt;API&lt;/span&gt;定義を、&lt;small&gt;（&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;のような）&lt;/small&gt;高度な型レベルプログラミングも、&lt;small&gt;（&lt;span class=&#34;ascii&#34;&gt;Yesod&lt;/span&gt;のような）&lt;/small&gt;&lt;span class=&#34;ascii&#34;&gt;TemplateHaskell&lt;/span&gt;もなしに可能にするライブラリーを目指していましたが、開発を途中で止めることにしました。その振り返り — とりわけ、そのゴールに基づいて実装するのが困難だと分かった機能などを中心にまとめます。&lt;/p&gt;
&lt;div id=&#34;table-of-contents-outer&#34;&gt;
&lt;div id=&#34;table-of-contents&#34;&gt;
&lt;div class=&#34;table-of-contents-title&#34;&gt;
Contents
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#動機&#34; title=&#34;動機&#34;&gt;動機&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#できたもの&#34; title=&#34;できたもの&#34;&gt;できたもの&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#最も単純な例&#34; title=&#34;最も単純な例&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;(1)&lt;/span&gt; 最も単純な例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#ステータスコードを指定した例&#34; title=&#34;ステータスコードを指定した例&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;(2)&lt;/span&gt; ステータスコードを指定した例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#パスの中に含まれる整数を処理する例&#34; title=&#34;パスの中に含まれる整数を処理する例&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;(3)&lt;/span&gt; パスの中に含まれる整数を処理する例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#content-typeを複数指定する&#34; title=&#34;content-typeを複数指定する&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Content-Type&lt;/span&gt;を複数指定する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#サーバーアプリケーションとしての使い方&#34; title=&#34;サーバーアプリケーションとしての使い方&#34;&gt;サーバーアプリケーションとしての使い方&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#template-haskellによるクライアントの生成&#34; title=&#34;template-haskellによるクライアントの生成&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Template Haskell&lt;/span&gt;による、クライアントの生成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#ドキュメントの生成&#34; title=&#34;ドキュメントの生成&#34;&gt;ドキュメントの生成&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#何故開発を止めるのか&#34; title=&#34;何故開発を止めるのか&#34;&gt;何故開発を止めるのか&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#想定通りにできなかったもの-レスポンスに複数のパターンがあるとき&#34; title=&#34;想定通りにできなかったもの-レスポンスに複数のパターンがあるとき&#34;&gt;想定通りにできなかったもの&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; レスポンスに複数のパターンがあるとき&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#パスのパーサー-実はがすでに危ない&#34; title=&#34;パスのパーサー-実はがすでに危ない&#34;&gt;パスのパーサー&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; 実は&lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt;がすでに危ない&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#実装し切れなかったもの&#34; title=&#34;実装し切れなかったもの&#34;&gt;実装し切れなかったもの&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#類似のライブラリー解決策&#34; title=&#34;類似のライブラリー解決策&#34;&gt;類似のライブラリー・解決策&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#okapi&#34; title=&#34;okapi&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Okapi&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#ihp&#34; title=&#34;ihp&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;IHP&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#終わりに&#34; title=&#34;終わりに&#34;&gt;終わりに&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id=&#34;動機&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#動機&#34; title=&#34;動機&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;動機&lt;/h1&gt;
&lt;p&gt;そもそも、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;には既に&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;や&lt;span class=&#34;ascii&#34;&gt;Yesod&lt;/span&gt;、&lt;span class=&#34;ascii&#34;&gt;Scotty&lt;/span&gt;といった人気のフレームワークがあるにもかかわらず、なぜ新しいフレームワークを作ろうと思ったのでしょうか。第&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;に、かつて私が&lt;a href=&#34;https://wiki.haskell.jp/Hikers%20Guide%20to%20Haskell.html#web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3&#34;&gt;「&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;の歩き方」という記事の「&lt;span class=&#34;ascii&#34;&gt;Web&lt;/span&gt;アプリケーション」の節&lt;/a&gt;で述べた、次の問題を解決したかったから、という理由があります&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ただし&lt;span class=&#34;ascii&#34;&gt;Servant, Yesod,&lt;/span&gt; 共通した困った特徴があります。
それぞれが&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;の高度な機能を利用した独特な&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;を提供しているため、仕組みがわかりづらい、という点です。
&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;は、「型レベルプログラミング」と呼ばれる、&lt;span class=&#34;ascii&#34;&gt;GHC&lt;/span&gt;の言語拡張を使った仕組みを駆使して、型宣言だけで&lt;span class=&#34;ascii&#34;&gt;REST API&lt;/span&gt;の仕様を記述できるようにしています。
&lt;span class=&#34;ascii&#34;&gt;Yesod&lt;/span&gt;も&lt;span class=&#34;ascii&#34;&gt;GHC&lt;/span&gt;の言語拡張をたくさん使っているのに加え、特に変わった特徴として、&lt;span class=&#34;ascii&#34;&gt;TemplateHaskell&lt;/span&gt;や&lt;span class=&#34;ascii&#34;&gt;QuasiQuote&lt;/span&gt;という仕組みを利用して、独自の&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;を提供しています。
それぞれ、見慣れた&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;と多かれ少なかれ異なる構文で書かなければいけない部分があるのです。
つまり、これらのうちどちらかを使う以上、どちらかの魔法を覚えなければならないのです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;この「どちらかの魔法を覚えなければならない」という問題は、初心者が&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;でウェブアプリケーションを作る上で大きな壁になりえます。入門書に書いてある&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;の機能だけでは、&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;や&lt;span class=&#34;ascii&#34;&gt;Yesod&lt;/span&gt;などのフレームワークで書くコードを理解できず、サンプルコードから雰囲気で書かなければならないのです。これが、新しいフレームワークを作ろうとした一番の動機です。&lt;/p&gt;
&lt;p&gt;その他、このフレームワークを開発し始めるより更に前から開発・執筆している、&lt;a href=&#34;https://github.com/haskell-jp/makeMistakesToLearnHaskell/&#34;&gt;「失敗しながら学ぶ&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;入門」&lt;/a&gt;をウェブアプリケーションとして公開する際のフレームワークとしても使おうという考えもありました。「失敗しながら学ぶ&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;入門」はタイトルの通り&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;入門者のためのコンテンツです。そのため、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;を学習したばかりの人でも簡単に修正できるフレームワークにしたかったのです。&lt;/p&gt;
&lt;h1 id=&#34;できたもの&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#できたもの&#34; title=&#34;できたもの&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;できたもの&lt;/h1&gt;
&lt;p&gt;ソースコードはこちら👇️にあります。名前は仮に「&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;」としました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/igrep/wai-sample&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;igrep/wai-sample: Prototype of a new web application framework based on WAI.&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;YouTube&lt;/span&gt;で配信する前から行っていた&lt;small&gt;（私の前職である）&lt;/small&gt;&lt;span class=&#34;ascii&#34;&gt;IIJ&lt;/span&gt;の社内勉強会中の開発と、全&lt;span class=&#34;ascii&#34;&gt;128&lt;/span&gt;回の&lt;span class=&#34;ascii&#34;&gt;YouTube&lt;/span&gt;でのライブコーディングを経て&lt;small&gt;（一部配信終了後に手を入れたこともありましたが）&lt;/small&gt;、次のような構文でウェブアプリケーションを記述できるようにしました&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE DataKinds         #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE OverloadedStrings #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE TypeApplications  #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-4&#34;&gt;&lt;a href=&#34;#cb1-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-5&#34;&gt;&lt;a href=&#34;#cb1-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WaiSample&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-6&#34;&gt;&lt;a href=&#34;#cb1-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-7&#34;&gt;&lt;a href=&#34;#cb1-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;sampleRoutes ::&lt;/span&gt; [&lt;span class=&#34;dt&#34;&gt;Handler&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&#34;cb1-8&#34;&gt;&lt;a href=&#34;#cb1-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;sampleRoutes &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-9&#34;&gt;&lt;a href=&#34;#cb1-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  [ &lt;span class=&#34;co&#34;&gt;-- ... 中略 ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-10&#34;&gt;&lt;a href=&#34;#cb1-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-11&#34;&gt;&lt;a href=&#34;#cb1-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;-- (1) 最も単純な例&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-12&#34;&gt;&lt;a href=&#34;#cb1-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  , get &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;T.Text&lt;/span&gt;) &lt;span class=&#34;st&#34;&gt;&amp;quot;aboutUs&amp;quot;&lt;/span&gt; (path &lt;span class=&#34;st&#34;&gt;&amp;quot;about/us&amp;quot;&lt;/span&gt;) (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;About IIJ&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb1-13&#34;&gt;&lt;a href=&#34;#cb1-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-14&#34;&gt;&lt;a href=&#34;#cb1-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;-- (2) ステータスコードを指定した例&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-15&#34;&gt;&lt;a href=&#34;#cb1-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  , get &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;WithStatus&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Status503&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;T.Text&lt;/span&gt;) &lt;span class=&#34;st&#34;&gt;&amp;quot;maintenance&amp;quot;&lt;/span&gt; (path &lt;span class=&#34;st&#34;&gt;&amp;quot;maintenance&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb1-16&#34;&gt;&lt;a href=&#34;#cb1-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Sorry, we are under maintenance&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb1-17&#34;&gt;&lt;a href=&#34;#cb1-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-18&#34;&gt;&lt;a href=&#34;#cb1-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;-- ... 中略 ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-19&#34;&gt;&lt;a href=&#34;#cb1-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-20&#34;&gt;&lt;a href=&#34;#cb1-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;-- (3) パスをパースして含まれる整数を取得する例&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-21&#34;&gt;&lt;a href=&#34;#cb1-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  , get &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;T.Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb1-22&#34;&gt;&lt;a href=&#34;#cb1-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;st&#34;&gt;&amp;quot;customerTransaction&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-23&#34;&gt;&lt;a href=&#34;#cb1-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      ( (,) &lt;span class=&#34;op&#34;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; (path &lt;span class=&#34;st&#34;&gt;&amp;quot;customer/&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;*&amp;gt;&lt;/span&gt; decimalPiece)&lt;/span&gt;
&lt;span id=&#34;cb1-24&#34;&gt;&lt;a href=&#34;#cb1-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;op&#34;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; (path &lt;span class=&#34;st&#34;&gt;&amp;quot;/transaction/&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;*&amp;gt;&lt;/span&gt; paramPiece)&lt;/span&gt;
&lt;span id=&#34;cb1-25&#34;&gt;&lt;a href=&#34;#cb1-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        )&lt;/span&gt;
&lt;span id=&#34;cb1-26&#34;&gt;&lt;a href=&#34;#cb1-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      (\(cId, transactionName) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-27&#34;&gt;&lt;a href=&#34;#cb1-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Customer &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; T.pack (&lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; cId) &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot; Transaction &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; transactionName&lt;/span&gt;
&lt;span id=&#34;cb1-28&#34;&gt;&lt;a href=&#34;#cb1-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        )&lt;/span&gt;
&lt;span id=&#34;cb1-29&#34;&gt;&lt;a href=&#34;#cb1-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-30&#34;&gt;&lt;a href=&#34;#cb1-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;-- ... 中略 ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-31&#34;&gt;&lt;a href=&#34;#cb1-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;※完全なサンプルコードは&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Sample.hs&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;WaiSample/Sample.hs&lt;/span&gt;&lt;/a&gt;をご覧ください。上記はその一部に説明用のコメントを加えています。&lt;/p&gt;
&lt;p&gt;上記のサンプルコードにおける&lt;code&gt;sampleRoutes&lt;/code&gt;が、&lt;span class=&#34;ascii&#34;&gt;Web API&lt;/span&gt;の仕様を定めている部分です&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;sampleRoutes ::&lt;/span&gt; [&lt;span class=&#34;dt&#34;&gt;Handler&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Handler&lt;/code&gt;という型のリストで、それぞれの&lt;code&gt;Handler&lt;/code&gt;には、&lt;span class=&#34;ascii&#34;&gt;Web API&lt;/span&gt;のエンドポイントを表すのに必要な情報が全て含まれています。&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;では、この&lt;code&gt;Handler&lt;/code&gt;のリストを解釈して&lt;span class=&#34;ascii&#34;&gt;WAI&lt;/span&gt;ベースのサーバーアプリケーションを実行したり、&lt;span class=&#34;ascii&#34;&gt;Template Haskell&lt;/span&gt;を通じてクライアントコードを生成したり、はたまたサーバーアプリケーションのドキュメントを生成したりすることができるようになっています。&lt;/p&gt;
&lt;h2 id=&#34;最も単純な例&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#最も単純な例&#34; title=&#34;最も単純な例&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;(1)&lt;/span&gt; 最も単純な例&lt;/h2&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;get &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;T.Text&lt;/span&gt;) &lt;span class=&#34;st&#34;&gt;&amp;quot;aboutUs&amp;quot;&lt;/span&gt; (path &lt;span class=&#34;st&#34;&gt;&amp;quot;about/us&amp;quot;&lt;/span&gt;) (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;About IIJ&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;先程のサンプルコードから抜粋した最も単純な例↑では、&lt;code&gt;get&lt;/code&gt;関数を使ってエンドポイントを定義しています。&lt;code&gt;get&lt;/code&gt;関数は名前のとおり&lt;span class=&#34;ascii&#34;&gt;HTTP&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;GET&lt;/span&gt;メソッドに対応するエンドポイントを定義します。&lt;code&gt;TypeApplications&lt;/code&gt;言語拡張を使って指定している&lt;code&gt;(PlainText, T.Text)&lt;/code&gt;という型が、このエンドポイントが返すレスポンスの型を表しています。ここでは、&lt;code&gt;get&lt;/code&gt;に渡す最後の引数に当たる関数（&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Types.hs#L104&#34;&gt;&lt;code&gt;Responder&lt;/code&gt;&lt;/a&gt;と呼びます。後述します）がレスポンスボディーとして返す型をお馴染みの&lt;code&gt;Text&lt;/code&gt;型として指定しつつ、サーバーやクライアントが処理する際は&lt;span class=&#34;ascii&#34;&gt;MIME&lt;/span&gt;タイプを&lt;code&gt;text/plain&lt;/code&gt;として扱うように指定しています。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;get&lt;/code&gt;関数の（値の）第&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;引数では、エンドポイントの名前を指定しています。この名前は、後述するクライアントコードを生成する機能において、関数名の一部として使われます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;get&lt;/code&gt;関数の第&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;引数は、エンドポイントのパスの仕様を表す&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Types.hs#L56-L65&#34;&gt;&lt;code&gt;Route&lt;/code&gt;型&lt;/a&gt;の値です。この例では、&lt;code&gt;path&lt;/code&gt;関数を使って&lt;code&gt;&#34;about/us&#34;&lt;/code&gt;という単純な文字列を指定しています。結果、このエンドポイントのパスは&lt;code&gt;/about/us&lt;/code&gt;となります&lt;a href=&#34;#fn1&#34; class=&#34;footnote-ref&#34; id=&#34;fnref1&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;）。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;get&lt;/code&gt;関数の最後の引数が、このエンドポイントが&lt;span class=&#34;ascii&#34;&gt;HTTP&lt;/span&gt;リクエストを受け取った際に実行する関数、&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Types.hs#L104&#34;&gt;&lt;code&gt;Responder&lt;/code&gt;&lt;/a&gt;です。ここでは、単純にレスポンスボディーとして文字列を返すだけの関数を指定しています。&lt;/p&gt;
&lt;h2 id=&#34;ステータスコードを指定した例&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#ステータスコードを指定した例&#34; title=&#34;ステータスコードを指定した例&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;(2)&lt;/span&gt; ステータスコードを指定した例&lt;/h2&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;get &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;WithStatus&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Status503&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;T.Text&lt;/span&gt;) &lt;span class=&#34;st&#34;&gt;&amp;quot;maintenance&amp;quot;&lt;/span&gt; (path &lt;span class=&#34;st&#34;&gt;&amp;quot;maintenance&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Sorry, we are under maintenance&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;デフォルトでは、&lt;code&gt;get&lt;/code&gt;関数で定義したエンドポイントはやっぱりステータスコード&lt;span class=&#34;ascii&#34;&gt;200&lt;/span&gt;（&lt;span class=&#34;ascii&#34;&gt;OK&lt;/span&gt;）を返します。この挙動を変えるには、先程指定したレスポンスの型のうち、&lt;span class=&#34;ascii&#34;&gt;MIME&lt;/span&gt;タイプを指定していた箇所を&lt;code&gt;WithStatus&lt;/code&gt;型でラップしましょう。型引数で指定しているタプルの&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つ目の要素は、このように&lt;span class=&#34;ascii&#34;&gt;HTTP&lt;/span&gt;のレスポンスに関する仕様を&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;の型で指定するパラメーターとなっています。&lt;/p&gt;
&lt;p&gt;この例では、&lt;code&gt;Status503&lt;/code&gt;という型を指定しているため、&lt;span class=&#34;ascii&#34;&gt;HTTP&lt;/span&gt;ステータスコード&lt;span class=&#34;ascii&#34;&gt;503&lt;/span&gt;（&lt;span class=&#34;ascii&#34;&gt;Service Unavailable&lt;/span&gt;）を返すエンドポイントを定義しています。&lt;/p&gt;
&lt;h2 id=&#34;パスの中に含まれる整数を処理する例&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#パスの中に含まれる整数を処理する例&#34; title=&#34;パスの中に含まれる整数を処理する例&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;(3)&lt;/span&gt; パスの中に含まれる整数を処理する例&lt;/h2&gt;
&lt;p&gt;よくある&lt;span class=&#34;ascii&#34;&gt;Web&lt;/span&gt;アプリケーションフレームワークでは、パスの一部に含まれる整数など、文字列型以外の値を取得するための仕組みが用意されています。&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;において、文字列から特定の型の値を取り出す…といえばそう、パーサーコンビネーターですね。&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;では、サーバーが受け取ったパスをパーサーコンビネーターでパースするようになっています。従って下記の例では、&lt;code&gt;/customer/123/transaction/abc&lt;/code&gt;というパスを受け取った場合、&lt;code&gt;123&lt;/code&gt;と&lt;code&gt;&#34;abc&#34;&lt;/code&gt;をタプルに詰め込んで&lt;code&gt;Responder&lt;/code&gt;に渡すパスのパーサーを定義しています&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;get &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;T.Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;st&#34;&gt;&amp;quot;customerTransaction&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-3&#34;&gt;&lt;a href=&#34;#cb5-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ( (,) &lt;span class=&#34;op&#34;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; (path &lt;span class=&#34;st&#34;&gt;&amp;quot;customer/&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;*&amp;gt;&lt;/span&gt; decimalPiece)&lt;/span&gt;
&lt;span id=&#34;cb5-4&#34;&gt;&lt;a href=&#34;#cb5-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;op&#34;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; (path &lt;span class=&#34;st&#34;&gt;&amp;quot;/transaction/&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;*&amp;gt;&lt;/span&gt; paramPiece)&lt;/span&gt;
&lt;span id=&#34;cb5-5&#34;&gt;&lt;a href=&#34;#cb5-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    )&lt;/span&gt;
&lt;span id=&#34;cb5-6&#34;&gt;&lt;a href=&#34;#cb5-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  (\(cId, transactionName) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-7&#34;&gt;&lt;a href=&#34;#cb5-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Customer &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; T.pack (&lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; cId) &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot; Transaction &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; transactionName&lt;/span&gt;
&lt;span id=&#34;cb5-8&#34;&gt;&lt;a href=&#34;#cb5-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    )&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;実際のところここまでの話は&lt;code&gt;Route&lt;/code&gt;型の値をサーバーアプリケーションが解釈した場合の挙動です。&lt;code&gt;Route&lt;/code&gt;型はパスの仕様を定義する&lt;code&gt;Applicative&lt;/code&gt;な内部&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;となっています。これによって、サーバーアプリケーションだけでなくクライアントのコード生成機能やドキュメントの生成など、様々な応用ができるようになっています。詳しくは後述しますが、例えばクライアントのコード生成機能が&lt;code&gt;Route&lt;/code&gt;型の値を解釈すると、&lt;code&gt;decimalPiece&lt;/code&gt;や&lt;code&gt;paramPiece&lt;/code&gt;などの値は生成した関数の引数を&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つずつ追加します。&lt;/p&gt;
&lt;h2 id=&#34;content-typeを複数指定する&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#content-typeを複数指定する&#34; title=&#34;content-typeを複数指定する&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;Content-Type&lt;/span&gt;を複数指定する&lt;/h2&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Ruby on Rails&lt;/span&gt;の&lt;code&gt;respond_to&lt;/code&gt;メソッドなどで実現できるように、&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つのエンドポイントで&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの種類のレスポンスボディーを、複数の&lt;span class=&#34;ascii&#34;&gt;Content-Type&lt;/span&gt;で返す、といった機能は昨今の&lt;span class=&#34;ascii&#34;&gt;Web&lt;/span&gt;アプリケーションフレームワークではごく一般的な機能でしょう。&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;の場合、例えば次のようにして、&lt;code&gt;Customer&lt;/code&gt;という型の値を&lt;span class=&#34;ascii&#34;&gt;JSON&lt;/span&gt;や&lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;な文字列として返すエンドポイントを定義できます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;sampleRoutes &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-2&#34;&gt;&lt;a href=&#34;#cb6-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  [ &lt;span class=&#34;co&#34;&gt;-- ... 中略 ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-3&#34;&gt;&lt;a href=&#34;#cb6-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  , get &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;ContentTypes&lt;/span&gt; &amp;#39;[&lt;span class=&#34;dt&#34;&gt;Json&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;FormUrlEncoded&lt;/span&gt;], &lt;span class=&#34;dt&#34;&gt;Customer&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb6-4&#34;&gt;&lt;a href=&#34;#cb6-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;-- ... 中略 ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-5&#34;&gt;&lt;a href=&#34;#cb6-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これまでの例では&lt;code&gt;get&lt;/code&gt;の型引数において&lt;span class=&#34;ascii&#34;&gt;MIME&lt;/span&gt;タイプを表す箇所に&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの型のみ（&lt;code&gt;PlainText&lt;/code&gt;型）を指定していましたが、ここでは代わりに&lt;code&gt;ContentTypes&lt;/code&gt;という型を使用しています。&lt;code&gt;ContentTypes&lt;/code&gt;型コンストラクターに、&lt;span class=&#34;ascii&#34;&gt;MIME&lt;/span&gt;タイプを表す型の型レベルリストを渡せば、レスポンスボディーを表す&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの型に対して、複数の&lt;span class=&#34;ascii&#34;&gt;MIME&lt;/span&gt;タイプを指定できるようになります。&lt;/p&gt;
&lt;p&gt;なお、&lt;code&gt;Json&lt;/code&gt;や&lt;code&gt;FormUrlEncoded&lt;/code&gt;と一緒に指定した&lt;code&gt;Customer&lt;/code&gt;型は、当然&lt;a href=&#34;https://hackage.haskell.org/package/aeson/docs/Data-Aeson-Types.html#t:ToJSON&#34;&gt;&lt;code&gt;ToJSON&lt;/code&gt;&lt;/a&gt;・&lt;a href=&#34;https://hackage.haskell.org/package/aeson/docs/Data-Aeson-Types.html#t:FromJSON&#34;&gt;&lt;code&gt;FromJSON&lt;/code&gt;&lt;/a&gt;や&lt;a href=&#34;https://hackage.haskell.org/package/http-api-data/docs/Web-FormUrlEncoded.html#t:ToForm&#34;&gt;&lt;code&gt;ToForm&lt;/code&gt;&lt;/a&gt;・&lt;a href=&#34;https://hackage.haskell.org/package/http-api-data/docs/Web-FormUrlEncoded.html#t:FromForm&#34;&gt;&lt;code&gt;FromForm&lt;/code&gt;&lt;/a&gt;といった型クラスのインスタンスである必要があります&lt;a href=&#34;#fn2&#34; class=&#34;footnote-ref&#34; id=&#34;fnref2&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;。レスポンスボディーとして指定した型が、同時に指定した&lt;span class=&#34;ascii&#34;&gt;MIME&lt;/span&gt;タイプに対応する形式に変換できることを、保証できるようになっているのです。&lt;/p&gt;
&lt;h2 id=&#34;サーバーアプリケーションとしての使い方&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#サーバーアプリケーションとしての使い方&#34; title=&#34;サーバーアプリケーションとしての使い方&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;サーバーアプリケーションとしての使い方&lt;/h2&gt;
&lt;p&gt;ここまでで定義した&lt;code&gt;Handler&lt;/code&gt;型の値、すなわち&lt;span class=&#34;ascii&#34;&gt;Web API&lt;/span&gt;のエンドポイントの仕様に基づいてサーバーアプリケーションを実行するには、次のように書きます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb7&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb7-1&#34;&gt;&lt;a href=&#34;#cb7-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Network.Wai&lt;/span&gt;              (&lt;span class=&#34;dt&#34;&gt;Application&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb7-2&#34;&gt;&lt;a href=&#34;#cb7-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Network.Wai.Handler.Warp&lt;/span&gt; (runEnv)&lt;/span&gt;
&lt;span id=&#34;cb7-3&#34;&gt;&lt;a href=&#34;#cb7-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-4&#34;&gt;&lt;a href=&#34;#cb7-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WaiSample.Sample&lt;/span&gt;         (sampleRoutes)&lt;/span&gt;
&lt;span id=&#34;cb7-5&#34;&gt;&lt;a href=&#34;#cb7-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WaiSample.Server&lt;/span&gt;         (handles)&lt;/span&gt;
&lt;span id=&#34;cb7-6&#34;&gt;&lt;a href=&#34;#cb7-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-7&#34;&gt;&lt;a href=&#34;#cb7-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-8&#34;&gt;&lt;a href=&#34;#cb7-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;sampleApp ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Application&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-9&#34;&gt;&lt;a href=&#34;#cb7-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;sampleApp &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; handles sampleRoutes&lt;/span&gt;
&lt;span id=&#34;cb7-10&#34;&gt;&lt;a href=&#34;#cb7-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-11&#34;&gt;&lt;a href=&#34;#cb7-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-12&#34;&gt;&lt;a href=&#34;#cb7-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;runSampleApp ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb7-13&#34;&gt;&lt;a href=&#34;#cb7-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;runSampleApp &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; runEnv &lt;span class=&#34;dv&#34;&gt;8020&lt;/span&gt; sampleApp&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ℹ️&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Server/Sample.hs&#34;&gt;こちら&lt;/a&gt;にあるコードと同じ内容です。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;get&lt;/code&gt;関数などで作った&lt;code&gt;Handler&lt;/code&gt;型のリストを&lt;code&gt;handles&lt;/code&gt;関数に渡すと、&lt;span class=&#34;ascii&#34;&gt;WAI&lt;/span&gt;の&lt;a href=&#34;https://hackage.haskell.org/package/wai-3.2.4/docs/Network-Wai.html#t:Application&#34;&gt;&lt;code&gt;Application&lt;/code&gt;&lt;/a&gt;型の値が出来上がります。&lt;code&gt;Application&lt;/code&gt;型は&lt;span class=&#34;ascii&#34;&gt;WAI&lt;/span&gt;におけるサーバーアプリケーションを表す型で、&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;や&lt;span class=&#34;ascii&#34;&gt;Yesod&lt;/span&gt;など他の多くの&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;製フレームワークでも、最終的にこの&lt;code&gt;Application&lt;/code&gt;型の値を作るよう設計されています。上記の例は&lt;code&gt;Application&lt;/code&gt;型の値を&lt;span class=&#34;ascii&#34;&gt;Warp&lt;/span&gt;というウェブサーバーで動かす場合のコードです。&lt;code&gt;Application&lt;/code&gt;型の値を&lt;span class=&#34;ascii&#34;&gt;Warp&lt;/span&gt;の&lt;code&gt;runEnv&lt;/code&gt;関数に渡すことで、指定したポート番号でアプリケーションを起動できます。&lt;/p&gt;
&lt;p&gt;ここで起動したサーバーアプリケーションが、実際にエンドポイントへのリクエストを受け取った際実行する関数は、&lt;code&gt;get&lt;/code&gt;関数などの最後の引数にあたる関数です。その関数は&lt;code&gt;SimpleResponder&lt;/code&gt;という型シノニム&lt;a href=&#34;#fn3&#34; class=&#34;footnote-ref&#34; id=&#34;fnref3&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;が設定されており、次のような定義となっています&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb8&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb8-1&#34;&gt;&lt;a href=&#34;#cb8-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;SimpleResponder&lt;/span&gt; p resObj &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; p &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; resObj&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ℹ️&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Types.hs#L106&#34;&gt;こちら&lt;/a&gt;より&lt;/p&gt;
&lt;p&gt;型パラメーター&lt;code&gt;p&lt;/code&gt;は、エンドポイントのパスに含まれるパラメーターを表す型です。これまでの例で&lt;code&gt;get&lt;/code&gt;関数に渡した&lt;code&gt;(path &#34;about/us&#34;)&lt;/code&gt;や&lt;code&gt;((,) &amp;lt;$&amp;gt; (path &#34;customer/&#34; *&amp;gt; decimalPiece) &amp;lt;*&amp;gt; (path &#34;/transaction/&#34; *&amp;gt; paramPiece))&lt;/code&gt;という式で作られる、&lt;code&gt;Route&lt;/code&gt;型の値を解釈した結果の型&lt;code&gt;p&lt;/code&gt;です。&lt;/p&gt;
&lt;p&gt;そして&lt;code&gt;resObj&lt;/code&gt;は、エンドポイントが返すレスポンスボディーの型です。これまでの例でいうと、&lt;code&gt;get&lt;/code&gt;関数の型引数で指定した&lt;code&gt;(PlainText, T.Text)&lt;/code&gt;における&lt;code&gt;T.Text&lt;/code&gt;型、&lt;code&gt;(ContentTypes &#39;[Json, FormUrlEncoded], Customer)&lt;/code&gt;における&lt;code&gt;Customer&lt;/code&gt;型が該当します。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;runSampleApp&lt;/code&gt;は各&lt;code&gt;Handler&lt;/code&gt;型の値を解釈し、サーバーアプリケーションとして実行します。エンドポイントのパスの仕様（&lt;code&gt;(path &#34;about/us&#34;)&lt;/code&gt;など）をパーサーコンビネーターとして解釈し&lt;a href=&#34;#fn4&#34; class=&#34;footnote-ref&#34; id=&#34;fnref4&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt;、パースが成功した&lt;code&gt;Handler&lt;/code&gt;が持つ&lt;code&gt;SimpleResponder&lt;/code&gt;（&lt;code&gt;p -&amp;gt; IO resObj&lt;/code&gt;）を呼び出します。そして&lt;code&gt;SimpleResponder&lt;/code&gt;が返した&lt;code&gt;resObj&lt;/code&gt;を、クライアントが要求した&lt;span class=&#34;ascii&#34;&gt;MIME&lt;/span&gt;タイプに応じたレスポンスボディーに変換し、クライアントに返す、という流れで動くようになっています。&lt;/p&gt;
&lt;h2 id=&#34;template-haskellによるクライアントの生成&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#template-haskellによるクライアントの生成&#34; title=&#34;template-haskellによるクライアントの生成&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;Template Haskell&lt;/span&gt;による、クライアントの生成&lt;/h2&gt;
&lt;p&gt;サーバーアプリケーションの定義だけであれば、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;以外のものも含め、従来の多くのウェブアプリケーションフレームワークでも可能でしょう。しかし&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;を始め、昨今における&lt;span class=&#34;ascii&#34;&gt;REST API&lt;/span&gt;の開発を想定した&lt;span class=&#34;ascii&#34;&gt;Web&lt;/span&gt;アプリケーションフレームワークは、クライアントコードを生成する機能まで備えていることが多いです。&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;はそうしたフレームワークを目指しているため、当然クライアントコードの生成もできるようになっています&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb9&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb9-1&#34;&gt;&lt;a href=&#34;#cb9-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE DataKinds        #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-2&#34;&gt;&lt;a href=&#34;#cb9-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE TemplateHaskell  #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-3&#34;&gt;&lt;a href=&#34;#cb9-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE TypeApplications #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-4&#34;&gt;&lt;a href=&#34;#cb9-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-5&#34;&gt;&lt;a href=&#34;#cb9-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WaiSample.Client&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-6&#34;&gt;&lt;a href=&#34;#cb9-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WaiSample.Sample&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-7&#34;&gt;&lt;a href=&#34;#cb9-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-8&#34;&gt;&lt;a href=&#34;#cb9-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-9&#34;&gt;&lt;a href=&#34;#cb9-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;$&lt;/span&gt;(declareClient &lt;span class=&#34;st&#34;&gt;&amp;quot;sample&amp;quot;&lt;/span&gt; sampleRoutes)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ℹ️&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Client/Sample.hs&#34;&gt;こちら&lt;/a&gt;からほぼそのままコピペしたコードです。&lt;/p&gt;
&lt;p&gt;上記の通り、クライアントコードの生成は&lt;code&gt;TemplateHaskell&lt;/code&gt;を使って行います。「簡単な&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;のみで作る」という目標からは早くも外れてしまいますが、生成されるコードが十分に予測しやすいものであろうことや、考え得る限り何らかの形で「難しい&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;」を使わなければ実装できないだろうという推察から、&lt;code&gt;TemplateHaskell&lt;/code&gt;を使うことにしました。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;declareClient&lt;/code&gt;という関数に、生成する関数の名前の接頭辞（&lt;span class=&#34;ascii&#34;&gt;prefix&lt;/span&gt;）とこれまで定義した&lt;code&gt;Handler&lt;/code&gt;型のリスト（&lt;code&gt;sampleRoutes&lt;/code&gt;）を渡すと、次のような型の関数の定義を生成します&lt;a href=&#34;#fn5&#34; class=&#34;footnote-ref&#34; id=&#34;fnref5&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt;&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb10&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb10-1&#34;&gt;&lt;a href=&#34;#cb10-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;sampleAboutUs ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Backend&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-2&#34;&gt;&lt;a href=&#34;#cb10-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;sampleMaintenance ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Backend&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-3&#34;&gt;&lt;a href=&#34;#cb10-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;sampleCustomerTransaction ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Backend&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Integer&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;生成された関数は、&lt;code&gt;get&lt;/code&gt;関数などの第&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;引数として渡した関数の名前に、&lt;code&gt;declareClient&lt;/code&gt;の第&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;引数として渡した接頭辞が付いた名前で定義されます。&lt;/p&gt;
&lt;p&gt;生成された関数の第&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;引数、&lt;code&gt;Backend&lt;/code&gt;型は、クライアントがサーバーアプリケーションに実際に&lt;span class=&#34;ascii&#34;&gt;HTTP&lt;/span&gt;リクエストを送るための関数です。次のように定義されています&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb11&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb11-1&#34;&gt;&lt;a href=&#34;#cb11-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.ByteString.Lazy.Char8&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;BL&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb11-2&#34;&gt;&lt;a href=&#34;#cb11-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Network.HTTP.Client&lt;/span&gt;        &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;HC&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb11-3&#34;&gt;&lt;a href=&#34;#cb11-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb11-4&#34;&gt;&lt;a href=&#34;#cb11-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Backend&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Method&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Url&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;RequestHeaders&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;HC.Response&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;BL.ByteString&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このバックエンドを、例えば&lt;code&gt;http-client&lt;/code&gt;パッケージの関数を使って実装することで、生成された関数がサーバーアプリケーションにリクエストを送ることができます。以下は実際に&lt;code&gt;http-client&lt;/code&gt;パッケージを使って実装したバックエンドの例です&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb12&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb12-1&#34;&gt;&lt;a href=&#34;#cb12-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Network.HTTP.Client&lt;/span&gt;        &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;HC&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-2&#34;&gt;&lt;a href=&#34;#cb12-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.ByteString.UTF8&lt;/span&gt;       &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;BS&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-3&#34;&gt;&lt;a href=&#34;#cb12-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-4&#34;&gt;&lt;a href=&#34;#cb12-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;httpClientBackend ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Manager&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Backend&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-5&#34;&gt;&lt;a href=&#34;#cb12-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;httpClientBackend rootUrl manager method pathPieces rawReqHds &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-6&#34;&gt;&lt;a href=&#34;#cb12-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  req0 &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; parseUrlThrow &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; BS.toString &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; method &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; B.pack &lt;span class=&#34;st&#34;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; BS.fromString rootUrl &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; pathPieces&lt;/span&gt;
&lt;span id=&#34;cb12-7&#34;&gt;&lt;a href=&#34;#cb12-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; req &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; req0 { HC.requestHeaders &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; rawReqHds }&lt;/span&gt;
&lt;span id=&#34;cb12-8&#34;&gt;&lt;a href=&#34;#cb12-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  httpLbs (setRequestIgnoreStatus req) manager&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ℹ️&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Client.hs#L225-L230&#34;&gt;こちら&lt;/a&gt;からほぼそのままコピペしたコードです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Backend&lt;/code&gt;型以外の引数は、パスパラメーターを始めとする、&lt;span class=&#34;ascii&#34;&gt;HTTP&lt;/span&gt;リクエストを組み立てるのに必要な情報です。&lt;code&gt;get&lt;/code&gt;関数などで&lt;code&gt;Handler&lt;/code&gt;型の値を定義する際に指定した&lt;code&gt;decimalPiece&lt;/code&gt;や&lt;code&gt;paramPiece&lt;/code&gt;を&lt;code&gt;declareClient&lt;/code&gt;関数が回収して、生成した関数の引数に追加します。実際に生成した関数が受け取った引数は、もちろんパスの一部として当てはめるのに用います。&lt;/p&gt;
&lt;p&gt;生成した関数の戻り値は、サーバーからのレスポンスを表す型です。&lt;code&gt;get&lt;/code&gt;関数の型引数として渡した&lt;code&gt;(PlainText, T.Text)&lt;/code&gt;や&lt;code&gt;(ContentTypes &#39;[Json, FormUrlEncoded], Customer)&lt;/code&gt;などにおける&lt;code&gt;T.Text&lt;/code&gt;や&lt;code&gt;Customer&lt;/code&gt;がそれに当たります。クライアントの関数はサーバーからのレスポンスを、&lt;span class=&#34;ascii&#34;&gt;MIME&lt;/span&gt;タイプを表す型などに従って、この型に変換してから返すよう実装されているのです。&lt;/p&gt;
&lt;h2 id=&#34;ドキュメントの生成&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#ドキュメントの生成&#34; title=&#34;ドキュメントの生成&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;ドキュメントの生成&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/servant-openapi3&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;では&lt;span class=&#34;ascii&#34;&gt;OpenAPI&lt;/span&gt;に則ったドキュメントを生成するパッケージがある&lt;/a&gt;ように、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;の構文で定義した&lt;span class=&#34;ascii&#34;&gt;REST API&lt;/span&gt;の仕様から、&lt;span class=&#34;ascii&#34;&gt;API&lt;/span&gt;のドキュメントを生成する機能があると便利でしょう。&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;でも、&lt;code&gt;Handler&lt;/code&gt;型のリストから&lt;span class=&#34;ascii&#34;&gt;API&lt;/span&gt;のドキュメントを生成する機能を実装しました — 残念ながら完成度が低く、とても実用に耐えるものではありませんが。&lt;/p&gt;
&lt;p&gt;ともあれ、試しに使ってみましょう。これまで例として紹介した&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Sample.hs#L147&#34;&gt;&lt;code&gt;sampleRoutes&lt;/code&gt;&lt;/a&gt;の各&lt;code&gt;Handler&lt;/code&gt;に&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample.hs#L47&#34;&gt;&lt;code&gt;showHandlerSpec&lt;/code&gt;&lt;/a&gt;という関数を適用すると、次のように各エンドポイントへのパスやリクエスト・レスポンスの情報を取得することが出来ます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb13&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb13-1&#34;&gt;&lt;a href=&#34;#cb13-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;mapM_&lt;/span&gt; (TIO.putStrLn &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; showHandlerSpec) sampleRoutes&lt;/span&gt;
&lt;span id=&#34;cb13-2&#34;&gt;&lt;a href=&#34;#cb13-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;index&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;GET&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;/&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-3&#34;&gt;&lt;a href=&#34;#cb13-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-4&#34;&gt;&lt;a href=&#34;#cb13-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Query&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Params&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-5&#34;&gt;&lt;a href=&#34;#cb13-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Headers&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-6&#34;&gt;&lt;a href=&#34;#cb13-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;,&lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb13-7&#34;&gt;&lt;a href=&#34;#cb13-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-8&#34;&gt;&lt;a href=&#34;#cb13-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;maintenance &lt;span class=&#34;st&#34;&gt;&amp;quot;GET&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;/&lt;/span&gt;maintenance&lt;/span&gt;
&lt;span id=&#34;cb13-9&#34;&gt;&lt;a href=&#34;#cb13-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-10&#34;&gt;&lt;a href=&#34;#cb13-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Query&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Params&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-11&#34;&gt;&lt;a href=&#34;#cb13-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Headers&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-12&#34;&gt;&lt;a href=&#34;#cb13-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; ((&lt;span class=&#34;dt&#34;&gt;WithStatus&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Status503&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;),&lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb13-13&#34;&gt;&lt;a href=&#34;#cb13-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-14&#34;&gt;&lt;a href=&#34;#cb13-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;aboutUs &lt;span class=&#34;st&#34;&gt;&amp;quot;GET&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;/&lt;/span&gt;about&lt;span class=&#34;op&#34;&gt;/&lt;/span&gt;us&lt;/span&gt;
&lt;span id=&#34;cb13-15&#34;&gt;&lt;a href=&#34;#cb13-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-16&#34;&gt;&lt;a href=&#34;#cb13-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Query&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Params&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-17&#34;&gt;&lt;a href=&#34;#cb13-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Headers&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-18&#34;&gt;&lt;a href=&#34;#cb13-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;,&lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb13-19&#34;&gt;&lt;a href=&#34;#cb13-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-20&#34;&gt;&lt;a href=&#34;#cb13-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- ... 中略 ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-21&#34;&gt;&lt;a href=&#34;#cb13-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-22&#34;&gt;&lt;a href=&#34;#cb13-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;customerTransaction &lt;span class=&#34;st&#34;&gt;&amp;quot;GET&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;/&lt;/span&gt;customer&lt;span class=&#34;op&#34;&gt;/:&lt;/span&gt;param&lt;span class=&#34;op&#34;&gt;/&lt;/span&gt;transaction&lt;span class=&#34;op&#34;&gt;/:&lt;/span&gt;param&lt;/span&gt;
&lt;span id=&#34;cb13-23&#34;&gt;&lt;a href=&#34;#cb13-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-24&#34;&gt;&lt;a href=&#34;#cb13-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Query&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Params&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-25&#34;&gt;&lt;a href=&#34;#cb13-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Headers&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-26&#34;&gt;&lt;a href=&#34;#cb13-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;,&lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb13-27&#34;&gt;&lt;a href=&#34;#cb13-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-28&#34;&gt;&lt;a href=&#34;#cb13-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;createProduct &lt;span class=&#34;st&#34;&gt;&amp;quot;POST&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;/&lt;/span&gt;products&lt;/span&gt;
&lt;span id=&#34;cb13-29&#34;&gt;&lt;a href=&#34;#cb13-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-30&#34;&gt;&lt;a href=&#34;#cb13-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Query&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Params&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-31&#34;&gt;&lt;a href=&#34;#cb13-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Headers&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (none)&lt;/span&gt;
&lt;span id=&#34;cb13-32&#34;&gt;&lt;a href=&#34;#cb13-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;,&lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb13-33&#34;&gt;&lt;a href=&#34;#cb13-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-34&#34;&gt;&lt;a href=&#34;#cb13-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- ... 以下略 ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;…が、前述の通りあまりに完成度が低いので、詳しくは解説しません。実際に上記のコード実行すると、&lt;code&gt;Response&lt;/code&gt;の型などがとても人間に読めるような出力になっていないことが分かります。今どきの&lt;span class=&#34;ascii&#34;&gt;Web API&lt;/span&gt;フレームワークであれば&lt;span class=&#34;ascii&#34;&gt;OpenAPI&lt;/span&gt;に則ったドキュメントを生成する機能が欲しいでしょうが、それもありません。この方向で拡張すれば実装できるとは思いますが、次の節で述べるとおり開発を止めることにしたので、ここまでとしておきます。&lt;/p&gt;
&lt;h1 id=&#34;何故開発を止めるのか&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#何故開発を止めるのか&#34; title=&#34;何故開発を止めるのか&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;何故開発を止めるのか&lt;/h1&gt;
&lt;p&gt;開発をやめる最も大きな理由は、冒頭でも触れたとおり、当初考えていたゴールを達成するのが難しいと判断したからです&lt;a href=&#34;#fn6&#34; class=&#34;footnote-ref&#34; id=&#34;fnref6&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/a&gt;。&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;のゴールは、「&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;のような型安全な&lt;span class=&#34;ascii&#34;&gt;API&lt;/span&gt;定義を、&lt;small&gt;（&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;のような）&lt;/small&gt;高度な型レベルプログラミングも、&lt;small&gt;（&lt;span class=&#34;ascii&#34;&gt;Yesod&lt;/span&gt;のような）&lt;/small&gt;&lt;span class=&#34;ascii&#34;&gt;TemplateHaskell&lt;/span&gt;もなしに可能にするライブラリー」にすることでした。ところが、後述の通りいくつかの機能においてそれが無理ではないか（少なくとも難しい）ということが発覚したのです。&lt;/p&gt;
&lt;h2 id=&#34;想定通りにできなかったもの-レスポンスに複数のパターンがあるとき&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#想定通りにできなかったもの-レスポンスに複数のパターンがあるとき&#34; title=&#34;想定通りにできなかったもの-レスポンスに複数のパターンがあるとき&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;想定通りにできなかったもの&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; レスポンスに複数のパターンがあるとき&lt;/h2&gt;
&lt;p&gt;「できたもの」の節では割愛しましたが、&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;では、サーバーが返すレスポンスに複数のケースがあるエンドポイント — 例えば、一方ではステータスコード&lt;span class=&#34;ascii&#34;&gt;200 OK&lt;/span&gt;と共に取得できたリソースの情報を返しつつ、一方では&lt;span class=&#34;ascii&#34;&gt;403 Forbidden&lt;/span&gt;と共にエラーメッセージを返す — の実装もサポートしています。例えば次のように書けば、&lt;code&gt;/customer/:id.txt&lt;/code&gt;というパスで複数の種類のレスポンスを返すエンドポイントを定義することが出来ます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb14&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb14-1&#34;&gt;&lt;a href=&#34;#cb14-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;get &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;Sum&lt;/span&gt; &amp;#39;[(&lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;T.Text&lt;/span&gt;), &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;WithStatus&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Status503&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;) &lt;span class=&#34;dt&#34;&gt;T.Text&lt;/span&gt;])&lt;/span&gt;
&lt;span id=&#34;cb14-2&#34;&gt;&lt;a href=&#34;#cb14-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;st&#34;&gt;&amp;quot;customerIdTxt&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb14-3&#34;&gt;&lt;a href=&#34;#cb14-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;co&#34;&gt;-- /customer/:id.txt&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb14-4&#34;&gt;&lt;a href=&#34;#cb14-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      (path &lt;span class=&#34;st&#34;&gt;&amp;quot;customer/&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;*&amp;gt;&lt;/span&gt; decimalPiece &lt;span class=&#34;op&#34;&gt;&amp;lt;*&lt;/span&gt; path &lt;span class=&#34;st&#34;&gt;&amp;quot;.txt&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb14-5&#34;&gt;&lt;a href=&#34;#cb14-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      (\i &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb14-6&#34;&gt;&lt;a href=&#34;#cb14-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;kw&#34;&gt;if&lt;/span&gt; i &lt;span class=&#34;op&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;503&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb14-7&#34;&gt;&lt;a href=&#34;#cb14-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;kw&#34;&gt;then&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; sumLift &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;WithStatus&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Status503&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PlainText&lt;/span&gt;) (&lt;span class=&#34;st&#34;&gt;&amp;quot;error&amp;quot;&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;T.Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb14-8&#34;&gt;&lt;a href=&#34;#cb14-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;kw&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; sumLift &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Customer &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; T.pack (&lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; i))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ℹ️&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Sample.hs#L175-L182&#34;&gt;こちら&lt;/a&gt;からほぼそのままコピペしたコードです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;get&lt;/code&gt;関数の型引数に、随分仰々しい型が現れました。&lt;code&gt;Sum&lt;/code&gt;という型は、名前のとおり和型を作ります。型レベルリストの要素として&lt;span class=&#34;ascii&#34;&gt;Content-Type&lt;/span&gt;やステータスコードを表す型と、実際のレスポンスボディーの型を組み合わせたタプル（あるいは後述する&lt;code&gt;Response&lt;/code&gt;型）を渡すことで、複数のケースを持つレスポンスの型を定義しています。上記の例における&lt;code&gt;Sum &#39;[(PlainText, T.Text), Response (WithStatus Status503 PlainText) T.Text]&lt;/code&gt;は、次の&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つのケースを持つレスポンスの型を表しています&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ステータスコードが（デフォルトの）&lt;code&gt;200 OK&lt;/code&gt;で、&lt;span class=&#34;ascii&#34;&gt;Content-Type&lt;/span&gt;が&lt;code&gt;text/plain&lt;/code&gt;、レスポンスボディーを表す型が&lt;code&gt;Text&lt;/code&gt;型&lt;/li&gt;
&lt;li&gt;ステータスコードが&lt;code&gt;503 Service Unavailable&lt;/code&gt;で、&lt;span class=&#34;ascii&#34;&gt;Content-Type&lt;/span&gt;が&lt;code&gt;text/plain&lt;/code&gt;、レスポンスボディーを表す型が&lt;code&gt;Text&lt;/code&gt;型&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上のように書くことで実装できるようにはしたのですが、これによって当初の目的である「高度な型レベルプログラミングなしに実装する」という目標から外れてしまいました。型レベルリストは「高度な型レベルプログラミング」に該当すると言って差し支えないでしょう。&lt;/p&gt;
&lt;p&gt;なぜこのような&lt;span class=&#34;ascii&#34;&gt;API&lt;/span&gt;になったのかというと、&lt;span class=&#34;ascii&#34;&gt;Web API&lt;/span&gt;に対する「入力」に当たる、パスのパース&lt;small&gt;（や、今回は実装しませんでしたがリクエストボディーなどの処理も）&lt;/small&gt;などと、&lt;span class=&#34;ascii&#34;&gt;Web API&lt;/span&gt;からの「出力」に当たるレスポンスの処理では、実行時に使える情報が大きく異なっていたからです。「入力」は値レベルでも&lt;small&gt;（高度な型レベルプログラミングなしで）&lt;/small&gt;&lt;span class=&#34;ascii&#34;&gt;Free Applicative&lt;/span&gt;を応用した&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;を使えば&lt;a href=&#34;#fn7&#34; class=&#34;footnote-ref&#34; id=&#34;fnref7&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;7&lt;/sup&gt;&lt;/a&gt;、サーバーアプリケーション・クライアントコード・ドキュメント、いずれにも実行時に解釈できるフレームワークにできた一方、レスポンスボディーなど「出力」の型は値レベルの&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;を書いても、サーバーアプリケーションを実行しない限りそれに整合しているかどうかが分からない、という原理的な問題が判明したからです。&lt;/p&gt;
&lt;p&gt;例えば、レスポンスボディーの仕様を次のような内部&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;で定義できるようにしたとします&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb15&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb15-1&#34;&gt;&lt;a href=&#34;#cb15-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;get [(plainText, text), ((withStatus status503 plainText), text)]&lt;/span&gt;
&lt;span id=&#34;cb15-2&#34;&gt;&lt;a href=&#34;#cb15-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;-- ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;型レベルプログラミングバージョンでは型引数に渡していた情報を、ほぼそのまま値レベルに落とし込んだものです。しかしこのように書いたとしても、サーバーアプリケーションを起動して、実際にクライアントからリクエストを受け取り、それに対して&lt;code&gt;get&lt;/code&gt;に渡した関数（&lt;code&gt;Responder&lt;/code&gt;）がレスポンスの元となる値を返すまで、レスポンスボディーの型が正しいかどうか、検証できないのです。「レスポンスの元となる値」の型はライブラリーのユーザー自身が&lt;code&gt;Responder&lt;/code&gt;で返す値の型ですし、実行時以前にコンパイル時に保証できていて欲しいものです。これが、値レベルの&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;を採用した場合の限界です。&lt;/p&gt;
&lt;p&gt;それから、型レベルリストを使ったこと以外においても、複雑で分かりづらい要因があります。先程から少し触れているとおり、&lt;span class=&#34;ascii&#34;&gt;Content-Type&lt;/span&gt;やステータスコードとレスポンスボディーの型を組み合わせを表すのに、タプル以外にも&lt;code&gt;Response&lt;/code&gt;という型を用いています。&lt;code&gt;Response&lt;/code&gt;型とタプル型はいずれも&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Types/Response.hs#L47-L49&#34;&gt;&lt;code&gt;ResponseSpec&lt;/code&gt;&lt;/a&gt;（下記に転載）という型クラスのインスタンスとなることで、「&lt;span class=&#34;ascii&#34;&gt;Content-Type&lt;/span&gt;やステータスコード」を表す型（&lt;code&gt;ResponseType&lt;/code&gt;）と&lt;code&gt;Responder&lt;/code&gt;がレスポンスボディーとして返す型（&lt;code&gt;ResponseObject&lt;/code&gt;）を宣言することが出来ます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb16&#34;&gt;&lt;pre class=&#34;sourceCode hs&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb16-1&#34;&gt;&lt;a href=&#34;#cb16-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ResponseSpec&lt;/span&gt; resSpec &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-2&#34;&gt;&lt;a href=&#34;#cb16-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ResponseType&lt;/span&gt; resSpec&lt;/span&gt;
&lt;span id=&#34;cb16-3&#34;&gt;&lt;a href=&#34;#cb16-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ResponseObject&lt;/span&gt; resSpec&lt;/span&gt;
&lt;span id=&#34;cb16-4&#34;&gt;&lt;a href=&#34;#cb16-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-5&#34;&gt;&lt;a href=&#34;#cb16-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ResponseSpec&lt;/span&gt; (resTyp, resObj) &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-6&#34;&gt;&lt;a href=&#34;#cb16-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ResponseType&lt;/span&gt; (resTyp, resObj) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; resTyp&lt;/span&gt;
&lt;span id=&#34;cb16-7&#34;&gt;&lt;a href=&#34;#cb16-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ResponseObject&lt;/span&gt; (resTyp, resObj) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; resObj&lt;/span&gt;
&lt;span id=&#34;cb16-8&#34;&gt;&lt;a href=&#34;#cb16-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-9&#34;&gt;&lt;a href=&#34;#cb16-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ResponseSpec&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; resTyp resObj) &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-10&#34;&gt;&lt;a href=&#34;#cb16-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ResponseType&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; resTyp resObj) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; resTyp&lt;/span&gt;
&lt;span id=&#34;cb16-11&#34;&gt;&lt;a href=&#34;#cb16-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ResponseObject&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; resTyp resObj) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; resTyp resObj&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ResponseSpec (resTyp, resObj)&lt;/code&gt;と&lt;code&gt;ResponseSpec (Response resTyp resObj)&lt;/code&gt;の&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つのインスタンスの違い、分かるでしょうか？まるで間違い探しですよね…😥。タプル型も&lt;code&gt;Response&lt;/code&gt;型も&lt;code&gt;get&lt;/code&gt;などに渡す型レベルリストでの役割はほぼ同じで、最初はタプルだけをとることにしていたのですが、やむを得ない理由があって&lt;code&gt;Response&lt;/code&gt;を別途設けることにしました&lt;a href=&#34;#fn8&#34; class=&#34;footnote-ref&#34; id=&#34;fnref8&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;8&lt;/sup&gt;&lt;/a&gt;。こうした分かりづらい部分が出来てしまったのも、失敗の&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つです。&lt;/p&gt;
&lt;h2 id=&#34;パスのパーサー-実はがすでに危ない&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#パスのパーサー-実はがすでに危ない&#34; title=&#34;パスのパーサー-実はがすでに危ない&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;パスのパーサー&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; 実は&lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt;がすでに危ない&lt;/h2&gt;
&lt;p&gt;パスのパーサーを値レベルの、&lt;code&gt;Applicative&lt;/code&gt;な内部&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;として実装した結果、&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;と比べて型安全性を損なってしまうという問題があることも、作ってから気付きました。例えば、次のように&lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt;に渡す関数としてコンストラクターでない、普通の関数を渡した場合です&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb17&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb17-1&#34;&gt;&lt;a href=&#34;#cb17-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;path &lt;span class=&#34;st&#34;&gt;&amp;quot;integers/&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;*&amp;gt;&lt;/span&gt; (&lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; decimalPiece)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Routes.hs#L22&#34;&gt;&lt;code&gt;decimalPiece&lt;/code&gt;&lt;/a&gt;は&lt;code&gt;Route Integer&lt;/code&gt;という型で、それに&lt;code&gt;show &amp;lt;$&amp;gt;&lt;/code&gt;を適用した結果は&lt;code&gt;Route String&lt;/code&gt;となります。&lt;code&gt;Route String&lt;/code&gt;は、パスの一部として文字列を受け取ることを表す型ですから、上記の式は&lt;code&gt;integers/&amp;lt;任意の文字列&amp;gt;&lt;/code&gt;というパスを表すことになります。ところが！実際にサーバーアプリケーションがパスをパースするのに使っているのは&lt;code&gt;decimalPiece&lt;/code&gt;なので、整数でなければなりません。このように&lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt;を使うだけで、&lt;code&gt;Route String&lt;/code&gt;という型が表すパスのパーサーと、実際にパースできるパスの仕様が食い違ってしまうことがあります。&lt;code&gt;Applicative&lt;/code&gt;（厳密に言えば&lt;code&gt;Functor&lt;/code&gt;の機能ですが）を使った&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;である以上、こうしたことが防げないのです。&lt;/p&gt;
&lt;p&gt;まあ、実は同じ問題が同じように&lt;code&gt;Applicative&lt;/code&gt;ベースの内部&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;を使った他のライブラリーにもあるでしょうから、敢えて気にしない、という手もあるのかも知れませんが。ちなみに、似たような問題を解決するため&lt;a href=&#34;https://hackage.haskell.org/package/relational-record&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;relational-record&lt;/span&gt;&lt;/a&gt;というパッケージでは&lt;code&gt;Functor&lt;/code&gt;や&lt;code&gt;Applicative&lt;/code&gt;は使わず、&lt;a href=&#34;https://hackage.haskell.org/package/product-isomorphic&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;product-isomorphic&lt;/span&gt;&lt;/a&gt;というパッケージで、言わば「コンストラクターだけが適用できる&lt;code&gt;Functor&lt;/code&gt;・&lt;code&gt;Applicative&lt;/code&gt;」とも言うべき専用の型クラスを作ることで解決していました。&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;もこれを使えないかと企みましたが、どうもうまく適用できなかったため諦めました。&lt;/p&gt;
&lt;h1 id=&#34;実装し切れなかったもの&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#実装し切れなかったもの&#34; title=&#34;実装し切れなかったもの&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;実装し切れなかったもの&lt;/h1&gt;
&lt;p&gt;ウェブアプリケーションフレームワークとして実装すべき機能のうち、実装し切れなかったものは当然たくさんあります。例えば以下のような機能でしょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;HTTP&lt;/span&gt;リクエストに関わるもの&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;リクエストヘッダーの処理&lt;/li&gt;
&lt;li&gt;クエリーパラメーターの処理&lt;/li&gt;
&lt;li&gt;（この辺りは、リクエストボディーの処理と似たような要領で実装できるはず）&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;HTTP&lt;/span&gt;レスポンスに関わるもの&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;動的な&lt;span class=&#34;ascii&#34;&gt;HTML&lt;/span&gt;の配信&lt;/li&gt;
&lt;li&gt;ファイルシステムにあるファイルの配信&lt;/li&gt;
&lt;li&gt;（&lt;span class=&#34;ascii&#34;&gt;REST API&lt;/span&gt;に特化したフレームワークであればこれらは不要でしょうが、拡張として簡単に追加できるようにはしたいですね）&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;両方に関わるもの&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;Cookie&lt;/span&gt;の読み書き&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;ドキュメント生成に関わるもの&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;OpenAPI&lt;/span&gt;に準拠したドキュメント生成&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;などなど！&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;類似のライブラリー解決策&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#類似のライブラリー解決策&#34; title=&#34;類似のライブラリー解決策&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;類似のライブラリー・解決策&lt;/h1&gt;
&lt;p&gt;手が遅いもので、私が最初に&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;のリポジトリーに対して行った&lt;a href=&#34;https://github.com/igrep/wai-sample/commit/37f49dfe86af7482b09ab82b2282c5b9bf1cd73d&#34;&gt;最初のコミット&lt;/a&gt;から、既に約&lt;span class=&#34;ascii&#34;&gt;5&lt;/span&gt;年の歳月が過ぎました&lt;a href=&#34;#fn9&#34; class=&#34;footnote-ref&#34; id=&#34;fnref9&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;9&lt;/sup&gt;&lt;/a&gt;。当時は私の前職、&lt;span class=&#34;ascii&#34;&gt;IIJ&lt;/span&gt;における社内勉強会のネタとして始めたのが懐かしいです。私が知る限り、当時は&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;のように「値レベルのプログラミングで」「&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;のように&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの定義からクライアントやドキュメントの生成も出来る」ことを目指したライブラリーはなかったように思います。しかし実際のところ、執筆時点で次のライブラリーが類似の機能を実装しているようです。これらのライブラリーがいつ開発を始めたのかは分かりませんが、やはり私が&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;を作り始めた時点で同じような問題意識を持った人はいたのでしょう。&lt;/p&gt;
&lt;h2 id=&#34;okapi&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#okapi&#34; title=&#34;okapi&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;a href=&#34;https://okapi.wiki/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Okapi&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://okapi.wiki/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Okapi&lt;/span&gt;&lt;/a&gt;にある&lt;a href=&#34;https://okapi.wiki/#endpoint&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Endpoint&lt;/span&gt;&lt;/a&gt;という機能は「&lt;span class=&#34;ascii&#34;&gt;An Endpoint is an executable specification representing a single Operation that can be taken against your API.&lt;/span&gt;」と謳っているとおり、&lt;span class=&#34;ascii&#34;&gt;API&lt;/span&gt;の仕様を表現する内部&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;を提供します。しかもこれから紹介するとおり、&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;より幾分洗練されているように見えます。&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Okapi&lt;/span&gt;では下記の&lt;code&gt;Endpoint&lt;/code&gt;という型 — &lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;でいう&lt;code&gt;Handler&lt;/code&gt;に相当するようです — に、「&lt;span class=&#34;ascii&#34;&gt;Script&lt;/span&gt;」と呼ばれる値レベル&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;を設定して使うようです&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb18&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb18-1&#34;&gt;&lt;a href=&#34;#cb18-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Endpoint&lt;/span&gt; p q h b r &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Endpoint&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb18-2&#34;&gt;&lt;a href=&#34;#cb18-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  {&lt;span class=&#34;ot&#34;&gt; method ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;StdMethod&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb18-3&#34;&gt;&lt;a href=&#34;#cb18-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ,&lt;span class=&#34;ot&#34;&gt; path ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Path.Script&lt;/span&gt; p&lt;/span&gt;
&lt;span id=&#34;cb18-4&#34;&gt;&lt;a href=&#34;#cb18-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ,&lt;span class=&#34;ot&#34;&gt; query ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Query.Script&lt;/span&gt; q&lt;/span&gt;
&lt;span id=&#34;cb18-5&#34;&gt;&lt;a href=&#34;#cb18-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ,&lt;span class=&#34;ot&#34;&gt; body ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Body.Script&lt;/span&gt; b&lt;/span&gt;
&lt;span id=&#34;cb18-6&#34;&gt;&lt;a href=&#34;#cb18-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ,&lt;span class=&#34;ot&#34;&gt; headers ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Headers.Script&lt;/span&gt; h&lt;/span&gt;
&lt;span id=&#34;cb18-7&#34;&gt;&lt;a href=&#34;#cb18-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ,&lt;span class=&#34;ot&#34;&gt; responder ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Responder.Script&lt;/span&gt; r&lt;/span&gt;
&lt;span id=&#34;cb18-8&#34;&gt;&lt;a href=&#34;#cb18-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;詳細はもちろん公式ドキュメントにも書かれていますが、読んでわかる範囲でこちらでも解説しましょう。&lt;code&gt;Endpoint&lt;/code&gt;型の各フィールドは、&lt;span class=&#34;ascii&#34;&gt;HTTP&lt;/span&gt;リクエスト・レスポンスに関わる各要素の仕様を表しています。&lt;code&gt;method&lt;/code&gt;フィールドを除くすべてのフィールドは、それぞれのフィールドのために作られた&lt;code&gt;Script&lt;/code&gt;という型の&lt;code&gt;Applicative&lt;/code&gt;&lt;a href=&#34;#fn10&#34; class=&#34;footnote-ref&#34; id=&#34;fnref10&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;10&lt;/sup&gt;&lt;/a&gt;な&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;を使って仕様を表現します。&lt;code&gt;Path.Script p&lt;/code&gt;はパスの仕様、&lt;code&gt;Query.Script q&lt;/code&gt;はクエリーパラメーターの仕様、&lt;code&gt;Body.Script b&lt;/code&gt;はリクエストボディーの仕様、&lt;code&gt;Headers.Script h&lt;/code&gt;はリクエストヘッダーの仕様、&lt;code&gt;Responder.Script r&lt;/code&gt;はレスポンスの仕様、といったところです。&lt;/p&gt;
&lt;p&gt;各&lt;code&gt;Script&lt;/code&gt;型のうち、特筆すべきは&lt;code&gt;Responder.Script&lt;/code&gt;でしょう。&lt;code&gt;Responder.Script&lt;/code&gt;では、レスポンスの種類毎にレスポンスボディーの型やステータスコード、レスポンスヘッダーの型を、&lt;span class=&#34;ascii&#34;&gt;case analysis&lt;/span&gt;を表す型として定義できるようになっています。そして、&lt;code&gt;Handler&lt;/code&gt;型は&lt;code&gt;Endpoint&lt;/code&gt;型が各種&lt;code&gt;Script&lt;/code&gt;を使って設定した値を使って、実際に&lt;code&gt;Response&lt;/code&gt;型の値を組み立てます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;（⚠️以下のコードは、&lt;a href=&#34;https://okapi.wiki/#cb10&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Okapi&lt;/span&gt;のドキュメントにあったサンプルコード&lt;/a&gt;を元に、私が推測してコメントを追加したものです。間違っていたらごめんなさい &lt;span class=&#34;ascii&#34;&gt;hask(_ _)eller&lt;/span&gt;）&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb19&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb19-1&#34;&gt;&lt;a href=&#34;#cb19-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- | Responseにヘッダーを設定する関数群&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-2&#34;&gt;&lt;a href=&#34;#cb19-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;SecretHeaders&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;SecretHeaders&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-3&#34;&gt;&lt;a href=&#34;#cb19-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  {&lt;span class=&#34;ot&#34;&gt; firstSecret ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-4&#34;&gt;&lt;a href=&#34;#cb19-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ,&lt;span class=&#34;ot&#34;&gt; secondSecret ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-5&#34;&gt;&lt;a href=&#34;#cb19-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  }&lt;/span&gt;
&lt;span id=&#34;cb19-6&#34;&gt;&lt;a href=&#34;#cb19-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-7&#34;&gt;&lt;a href=&#34;#cb19-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- | Responseにヘッダーとボディーを設定する関数群&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-8&#34;&gt;&lt;a href=&#34;#cb19-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--   レスポンスの種類毎にフィールドラベルを1つ備えた、case analysisを表す型&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-9&#34;&gt;&lt;a href=&#34;#cb19-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;MyResponders&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;MyResponders&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-10&#34;&gt;&lt;a href=&#34;#cb19-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  {&lt;span class=&#34;ot&#34;&gt; allGood ::&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;SecretHeaders&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-11&#34;&gt;&lt;a href=&#34;#cb19-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ,&lt;span class=&#34;ot&#34;&gt; notGood ::&lt;/span&gt; (() &lt;span class=&#34;op&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Response&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-12&#34;&gt;&lt;a href=&#34;#cb19-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  }&lt;/span&gt;
&lt;span id=&#34;cb19-13&#34;&gt;&lt;a href=&#34;#cb19-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-14&#34;&gt;&lt;a href=&#34;#cb19-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- | `Responder.Script`として定義する、レスポンスの仕様&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-15&#34;&gt;&lt;a href=&#34;#cb19-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;myResponderScript &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-16&#34;&gt;&lt;a href=&#34;#cb19-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;-- allGood の場合はレスポンスボディーは`Text`型で、ステータスコードは200。&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-17&#34;&gt;&lt;a href=&#34;#cb19-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;-- レスポンスヘッダーとしては、`IntSecret`と`X-Another-Secret`という&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-18&#34;&gt;&lt;a href=&#34;#cb19-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;-- `Int`型の2つのヘッダーを追加する。&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-19&#34;&gt;&lt;a href=&#34;#cb19-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  allGood &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; Responder.json &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt; status200 &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-20&#34;&gt;&lt;a href=&#34;#cb19-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    addSecret &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; AddHeader.using &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;IntSecret&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-21&#34;&gt;&lt;a href=&#34;#cb19-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    addAnotherSecret &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; AddHeader.using &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;X-Another-Secret&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-22&#34;&gt;&lt;a href=&#34;#cb19-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;pure&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;SecretHeaders&lt;/span&gt; {&lt;span class=&#34;op&#34;&gt;..&lt;/span&gt;}&lt;/span&gt;
&lt;span id=&#34;cb19-23&#34;&gt;&lt;a href=&#34;#cb19-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-24&#34;&gt;&lt;a href=&#34;#cb19-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;-- notGood の場合はレスポンスボディーは`Text`型で、ステータスコードは501。&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-25&#34;&gt;&lt;a href=&#34;#cb19-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;-- レスポンスヘッダーはなし。&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-26&#34;&gt;&lt;a href=&#34;#cb19-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  notGood &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; Responder.json &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt; status501 &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;pure&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb19-27&#34;&gt;&lt;a href=&#34;#cb19-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;pure&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;MyResponders&lt;/span&gt; {&lt;span class=&#34;op&#34;&gt;..&lt;/span&gt;}&lt;/span&gt;
&lt;span id=&#34;cb19-28&#34;&gt;&lt;a href=&#34;#cb19-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-29&#34;&gt;&lt;a href=&#34;#cb19-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- | Responder.Scriptで定義したcase analysisを表す型、`MyResponders`を使って、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-30&#34;&gt;&lt;a href=&#34;#cb19-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--   レスポンスを組み立てる関数。&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-31&#34;&gt;&lt;a href=&#34;#cb19-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--   `someNumber`が100未満なら`allGood`を、そうでなければ`notGood`を使う。&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-32&#34;&gt;&lt;a href=&#34;#cb19-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--   この関数が利用していない引数は、`Endpoint`型の他のフィールドに対応するもの。&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-33&#34;&gt;&lt;a href=&#34;#cb19-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;myHandler someNumber _ _ _ _ (&lt;span class=&#34;dt&#34;&gt;MyResponders&lt;/span&gt; allGood notGood) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-34&#34;&gt;&lt;a href=&#34;#cb19-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;if&lt;/span&gt; someNumber &lt;span class=&#34;op&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;100&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-35&#34;&gt;&lt;a href=&#34;#cb19-35&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;kw&#34;&gt;then&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; allGood&lt;/span&gt;
&lt;span id=&#34;cb19-36&#34;&gt;&lt;a href=&#34;#cb19-36&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      (\(&lt;span class=&#34;dt&#34;&gt;SecretHeaders&lt;/span&gt; firstSecret secondSecret) response &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; secondSecret &lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; firstSecret &lt;span class=&#34;dv&#34;&gt;7&lt;/span&gt; response)&lt;/span&gt;
&lt;span id=&#34;cb19-37&#34;&gt;&lt;a href=&#34;#cb19-37&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;st&#34;&gt;&amp;quot;All Good!&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-38&#34;&gt;&lt;a href=&#34;#cb19-38&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;kw&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; notGood&lt;/span&gt;
&lt;span id=&#34;cb19-39&#34;&gt;&lt;a href=&#34;#cb19-39&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      (\() response &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; response)&lt;/span&gt;
&lt;span id=&#34;cb19-40&#34;&gt;&lt;a href=&#34;#cb19-40&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;st&#34;&gt;&amp;quot;Not Good!&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;がうまく実装できなかった、レスポンスに複数のパターンがある場合の処理を、&lt;span class=&#34;ascii&#34;&gt;case analysis&lt;/span&gt;を表す型で実装しているのが興味深いですね。前述した「原理的な問題」に対する解決策なのでしょう。&lt;/p&gt;
&lt;h2 id=&#34;ihp&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#ihp&#34; title=&#34;ihp&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;a href=&#34;https://ihp.digitallyinduced.com/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;IHP&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;IHP (Integrated Haskell Platform)&lt;/span&gt;は、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;で書かれたフルスタックな&lt;span class=&#34;ascii&#34;&gt;Web&lt;/span&gt;アプリケーションフレームワークです。&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;のような、与えられたパスに基づいて対応する関数を呼び出す機能（ルーティング機能）はもちろんのこと、&lt;span class=&#34;ascii&#34;&gt;PostgreSQL&lt;/span&gt;と接続する&lt;span class=&#34;ascii&#34;&gt;ORM&lt;/span&gt;やメールの送信、バックグラウンド処理に加えて&lt;span class=&#34;ascii&#34;&gt;GUI&lt;/span&gt;から管理する機能など、様々な機能を備えています。&lt;a href=&#34;https://ihp.digitallyinduced.com/Guide/architecture.html&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Architecture&lt;/span&gt;&lt;/a&gt;を読むと察せられるとおり、古き良き&lt;span class=&#34;ascii&#34;&gt;Ruby on Rails&lt;/span&gt;のようなスタイルのフレームワークのようです。&lt;/p&gt;
&lt;p&gt;そんな&lt;a href=&#34;https://ihp.digitallyinduced.com/Guide/routing.html&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;IHP&lt;/span&gt;のルーティング機能&lt;/a&gt;、とりわけ&lt;span class=&#34;ascii&#34;&gt;REST API&lt;/span&gt;の慣習では表現しきれず、&lt;a href=&#34;https://ihp.digitallyinduced.com/Guide/routing.html#custom-routing&#34;&gt;カスタマイズしたパスを定義する際の機能&lt;/a&gt;は、まさにパスのパーサーコンビネーターを書くことで実装できるようになっています。以下はドキュメントにあった例をそのまま貼り付けています&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb20&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb20-1&#34;&gt;&lt;a href=&#34;#cb20-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- /posts/an-example-blog-post というような記事の名前(slug)や&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-2&#34;&gt;&lt;a href=&#34;#cb20-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- /posts/f85dc0bc-fc11-4341-a4e3-e047074a7982 というような記事のIDから&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-3&#34;&gt;&lt;a href=&#34;#cb20-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- 記事を表示するアクションを呼び出すルーティング&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-4&#34;&gt;&lt;a href=&#34;#cb20-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-5&#34;&gt;&lt;a href=&#34;#cb20-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- パスにあるパラメーターを表す型&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-6&#34;&gt;&lt;a href=&#34;#cb20-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PostsController&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-7&#34;&gt;&lt;a href=&#34;#cb20-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ShowPostAction&lt;/span&gt; {&lt;span class=&#34;ot&#34;&gt; postId ::&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;!&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Id&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Post&lt;/span&gt;)),&lt;span class=&#34;ot&#34;&gt; slug ::&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;!&lt;/span&gt;(&lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt;) }&lt;/span&gt;
&lt;span id=&#34;cb20-8&#34;&gt;&lt;a href=&#34;#cb20-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-9&#34;&gt;&lt;a href=&#34;#cb20-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-10&#34;&gt;&lt;a href=&#34;#cb20-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- CanRoute 型クラスのインスタンスで、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-11&#34;&gt;&lt;a href=&#34;#cb20-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- パスのパーサーコンビネーターを定義する&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-12&#34;&gt;&lt;a href=&#34;#cb20-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CanRoute&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PostsController&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-13&#34;&gt;&lt;a href=&#34;#cb20-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    parseRoute&amp;#39; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-14&#34;&gt;&lt;a href=&#34;#cb20-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        string &lt;span class=&#34;st&#34;&gt;&amp;quot;/posts/&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-15&#34;&gt;&lt;a href=&#34;#cb20-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; postById &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; parseId; endOfInput; &lt;span class=&#34;fu&#34;&gt;pure&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ShowPostAction&lt;/span&gt; { postId &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;id&lt;/span&gt;, slug &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt; }&lt;/span&gt;
&lt;span id=&#34;cb20-16&#34;&gt;&lt;a href=&#34;#cb20-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; postBySlug &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt; slug &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; remainingText; &lt;span class=&#34;fu&#34;&gt;pure&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ShowPostAction&lt;/span&gt; { postId &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt;, slug &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; slug }&lt;/span&gt;
&lt;span id=&#34;cb20-17&#34;&gt;&lt;a href=&#34;#cb20-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        postById &lt;span class=&#34;op&#34;&gt;&amp;lt;|&amp;gt;&lt;/span&gt; postBySlug&lt;/span&gt;
&lt;span id=&#34;cb20-18&#34;&gt;&lt;a href=&#34;#cb20-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-19&#34;&gt;&lt;a href=&#34;#cb20-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-20&#34;&gt;&lt;a href=&#34;#cb20-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- HasPath 型クラスのインスタンスで、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-21&#34;&gt;&lt;a href=&#34;#cb20-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- パスに含めるパラメーターからパスを生成する関数を定義する&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-22&#34;&gt;&lt;a href=&#34;#cb20-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;HasPath&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PostsController&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-23&#34;&gt;&lt;a href=&#34;#cb20-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    pathTo &lt;span class=&#34;dt&#34;&gt;ShowPostAction&lt;/span&gt; { postId &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;id&lt;/span&gt;, slug &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt; } &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;/posts/&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; tshow &lt;span class=&#34;fu&#34;&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-24&#34;&gt;&lt;a href=&#34;#cb20-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    pathTo &lt;span class=&#34;dt&#34;&gt;ShowPostAction&lt;/span&gt; { postId &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt;, slug &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; slug } &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;/posts/&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; slug&lt;/span&gt;
&lt;span id=&#34;cb20-25&#34;&gt;&lt;a href=&#34;#cb20-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-26&#34;&gt;&lt;a href=&#34;#cb20-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-27&#34;&gt;&lt;a href=&#34;#cb20-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;action &lt;span class=&#34;dt&#34;&gt;ShowPostAction&lt;/span&gt; { postId, slug } &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-28&#34;&gt;&lt;a href=&#34;#cb20-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    post &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt; slug &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-29&#34;&gt;&lt;a href=&#34;#cb20-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; slug &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; query &lt;span class=&#34;op&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Post&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;|&amp;gt;&lt;/span&gt; filterWhere (&lt;span class=&#34;op&#34;&gt;#&lt;/span&gt;slug, slug) &lt;span class=&#34;op&#34;&gt;|&amp;gt;&lt;/span&gt; fetchOne&lt;/span&gt;
&lt;span id=&#34;cb20-30&#34;&gt;&lt;a href=&#34;#cb20-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt;   &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; fetchOne postId&lt;/span&gt;
&lt;span id=&#34;cb20-31&#34;&gt;&lt;a href=&#34;#cb20-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;-- ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;や&lt;span class=&#34;ascii&#34;&gt;Okapi&lt;/span&gt;のようにパスの定義を&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;箇所で済ませられるわけではない（&lt;code&gt;CanRoute&lt;/code&gt;と&lt;code&gt;HasPath&lt;/code&gt;の&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つの型クラスのインスタンスを定義する必要がある）ようですが、パーサーコンビネーターを使って自由にパスを定義できるところは似ていますね。&lt;/p&gt;
&lt;h1 id=&#34;終わりに&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#終わりに&#34; title=&#34;終わりに&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;終わりに&lt;/h1&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;は、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;で&lt;span class=&#34;ascii&#34;&gt;Web API&lt;/span&gt;を実装するためのフレームワークとして、&lt;span class=&#34;ascii&#34;&gt;Servant&lt;/span&gt;や&lt;span class=&#34;ascii&#34;&gt;Yesod&lt;/span&gt;のような既存のフレームワークとは異なるアプローチを試みました。残念ながら目標の達成が技術的に困難であることが分かり、開発を止めることにしましたが、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;で&lt;span class=&#34;ascii&#34;&gt;Web API&lt;/span&gt;を実装するため新しいアプローチとして、何かしら参考になれば幸いです。&lt;/p&gt;
&lt;section id=&#34;footnotes&#34; class=&#34;footnotes footnotes-end-of-document&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn1&#34;&gt;&lt;p&gt;先頭のスラッシュにご注意ください。&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;が&lt;code&gt;Route&lt;/code&gt;型の値を処理する際は、先頭のスラッシュは付けない前提としています。&lt;a href=&#34;#fnref1&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn2&#34;&gt;&lt;p&gt;諸般の事情で、&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;では&lt;a href=&#34;https://github.com/igrep/http-api-data/tree/151de32409960354de3a3f786f20bc4a496d2b65&#34;&gt;&lt;code&gt;http-api-data&lt;/code&gt;パッケージをフォーク&lt;/a&gt;して使っています。そのため、&lt;code&gt;ToForm&lt;/code&gt;型クラスなどの仕様が&lt;span class=&#34;ascii&#34;&gt;Hackage&lt;/span&gt;にあるものと異なっています。最終的に&lt;span class=&#34;ascii&#34;&gt;wai-sample&lt;/span&gt;を公開する際、フォークした&lt;span class=&#34;ascii&#34;&gt;http-api-data&lt;/span&gt;を新しいパッケージとして同時に公開する予定でした。&lt;a href=&#34;#fnref2&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn3&#34;&gt;&lt;p&gt;名前から察せられるとおり&lt;code&gt;Simple&lt;/code&gt;じゃない普通の&lt;code&gt;Responder&lt;/code&gt;型もありますが、ここでは割愛します。&lt;code&gt;Responder&lt;/code&gt;型はクエリーパラメーターやリクエストヘッダーなど、パスに含めるパラメーター以外の情報を受け取るためのものです。&lt;code&gt;SimpleResponder&lt;/code&gt;型のすぐ近くで定義されているので、興味があったらご覧ください。&lt;a href=&#34;#fnref3&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn4&#34;&gt;&lt;p&gt;パーサーコンビネーター以外のアプローチ、例えば基数木を使ってより多くのエンドポイントを高速に処理できるようにするのも可能でしょう。&lt;a href=&#34;#fnref4&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn5&#34;&gt;&lt;p&gt;&lt;code&gt;ghc&lt;/code&gt;コマンドの&lt;code&gt;-ddump-splices&lt;/code&gt;オプションを使って、&lt;code&gt;declareClient&lt;/code&gt;関数が生成したコードを貼り付けました。みなさんの手元で試す場合は&lt;code&gt;stack build --ghc-options=-ddump-splices&lt;/code&gt;などと実行するのが簡単でしょう。&lt;a href=&#34;#fnref5&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn6&#34;&gt;&lt;p&gt;もう&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つは、大変申し訳ないですが、私自身の&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;に対する情熱が落ち込んでしまった、という理由もあります😞。&lt;a href=&#34;#fnref6&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn7&#34;&gt;&lt;p&gt;今回は詳細を省きましたが&lt;code&gt;Free Applicative&lt;/code&gt;を使った&lt;span class=&#34;ascii&#34;&gt;DSL&lt;/span&gt;の実装は、&lt;a href=&#34;https://github.com/igrep/wai-sample/blob/b4ddb75a28b927b76ac7c4c182bad6812769ed01/src/WaiSample/Types.hs&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;WaiSample.Types&lt;/span&gt;モジュール&lt;/a&gt;をご覧ください。&lt;a href=&#34;#fnref7&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn8&#34;&gt;&lt;p&gt;詳しい理由は面倒なので解説しません！これまでに出てきたコードだけで推測できるはずですし考えてみてください！&lt;a href=&#34;#fnref8&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn9&#34;&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/igrep/wai-sample/commit/b2647de2a1a4c7ec8c799ec07972c3d9df6fcb55&#34;&gt;実装に対する最後の修正&lt;/a&gt;からも既に&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;年以上が過ぎました。記録を作るのも遅い…😥&lt;a href=&#34;#fnref9&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn10&#34;&gt;&lt;p&gt;個人的には、なぜ&lt;code&gt;Alternative&lt;/code&gt;にしなかったのかが気になります。&lt;code&gt;Body.optional&lt;/code&gt;や&lt;code&gt;Headers.optional&lt;/code&gt;などは文字通り&lt;a href=&#34;https://hackage.haskell.org/package/base-4.21.0.0/docs/Control-Applicative.html#v:optional&#34;&gt;&lt;code&gt;Alternative&lt;/code&gt;の&lt;code&gt;optional&lt;/code&gt;&lt;/a&gt;で実現できそうに見えるからです。&lt;a href=&#34;#fnref10&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/2022/disband_admins.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;一般社団法人としてのHaskell-jp Admins解散のお知らせ&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&gt;

</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2025/09/11/%E9%A3%9B%E8%A1%8C%E6%A9%9F%E3%81%AE%E4%B8%AD%E3%81%A7_Haskell_%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B</id><title type="text">飛行機の中で Haskell プロジェクトをビルドする</title><updated>2025-09-11T09:34:22+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2025/09/11/%E9%A3%9B%E8%A1%8C%E6%A9%9F%E3%81%AE%E4%B8%AD%E3%81%A7_Haskell_%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B"/><summary type="html">いや別に飛行機の中でビルドするのが主題なわけではないのですが、オフラインモードのことを機内モードと言いますからね。最近の飛行機は Wi-Fi の提供があったりするらしいですが。 さて、あなたの Haskell プロジェクトをオフラインモードでビルドすることができますか？ まあ、今時オフライン環境も珍しいですし「そんな必要あるのか？」という感覚もあるかもしれません。Nix ではビルド再現性のためにオフライン環境でビルドできることが求められます1。 Nix で Haskell プロジェクトをビルドするには Input Output（iohk.io）の作成した haskell.nix が使用されるの…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2025/09/03/Shake_%E3%81%AE%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%81%8C%E5%8A%B9%E3%81%84%E3%81%A6%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F</id><title type="text">Shake のキャッシュが効いてなかった</title><updated>2025-09-03T00:37:06+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2025/09/03/Shake_%E3%81%AE%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%81%8C%E5%8A%B9%E3%81%84%E3%81%A6%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F"/><summary type="html">下記の記事を覚えていましょうか？ kakkun61.hatenablog.com Shake を使って静的ウェブサイト生成するようにしたことを書いた記事です。 ただ、どうも生成が遅いんです。しょっちゅうは更新しないので「まあいいか」と放置していたのですが、最近手を付けることがあったので改善してみました。 fsatrace はどう追跡してくれるのか 前方型1の Shake アクションの場合、「fsatrace で変更を追跡する」というようなことがリファレンスに書いてあり、「よく分からんけどそうなんか」ぐらいに思って使っていました。 hackage.haskell.org 実は fsatrace …</summary></entry><entry><id>https://blog.miz-ar.info/2025/06/side-effects/</id><title type="text">「関数の副作用の有無」よりも大事なもの</title><updated>2025-06-21T07:39:41+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2025/06/side-effects/"/><summary type="html">プログラミングをやっていると、「関数に副作用がある」とか「副作用がない」あるいは「純粋である」という話をちょいちょい耳にする。そして、「外界の状態を読み取るけど変更はしない関数」、例えば のような関数に副作用があるか？み [&amp;#8230;]</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2025/06/17/225129</id><title type="text">関数型まつり 2025 で AWS と定理証明について話してきました</title><updated>2025-06-17T22:51:30+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2025/06/17/225129"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された関数型まつりで、AWS によって開発されたポリシー言語 Cedar と、その開発に使用された定理証明支援系 Lean について登壇してきました。公募 CFP 枠です。 fortee.jp （TODO: 録画が公開されたら貼る） 前回登壇との関係 Cedar については、チェシャ猫自身が少し前、PHPerKaigi 2025 でも登壇しています。 前回と今回では、扱っている題材は同じですが、想定しているターゲットや興味の方向性が少し異なります。今回の登壇では Lean が保証している意味論的な定理や開発フローなど「Cedar がどのように設計・開発され…</summary></entry><entry><id>https://blog.miz-ar.info/2025/05/debugging-ghc-ci/</id><title type="text">GHCデバッグ日誌 CI編</title><updated>2025-05-29T13:05:14+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2025/05/debugging-ghc-ci/"/><summary type="html">私はHaskell処理系であるGHCに趣味で貢献しています。詳しいことは過去の記事を見てください： 今回は、GHCのCIの問題を追求した話をします。前に「GHCデバッグ日誌」という記事を書いたので、今回は「CI編」としま [&amp;#8230;]</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2025/03/25/025539</id><title type="text">PHPerKaigi 2025 で AWS のポリシー言語 Cedar について話してきました</title><updated>2025-05-11T23:33:55+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2025/03/25/025539"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された PHPerKaigi 2025 で、AWS によって開発されたポリシー言語 Cedar およびそのマネージドサービス版である Amazon Verified Permissions について登壇してきました。公募 CFP 枠です。 fortee.jp www.youtube.com 学習リソース もし、今回のトークを聞いて Cedar や Verified Permissions に興味を持った方がいたら、まずは公式で提供されているワークショップを触ってみることをお勧めします。ワークショップは以下の二種類があります。 Cedar policy la…</summary></entry><entry><id>https://blog.miz-ar.info/2025/04/ghc-simd-integer/</id><title type="text">GHCのSIMDサポートの進捗：整数ベクトルの演算</title><updated>2025-04-02T13:14:37+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2025/04/ghc-simd-integer/"/><summary type="html">ブログ等にちょいちょい書いていますが、私はこの数ヶ月ほどGHCのSIMDサポートの改善を進めています。 この3ヶ月間はx86 NCGで整数のSIMD演算を使えるようにするパッチを書いており、数日前にマージされました。一つ [&amp;#8230;]</summary></entry><entry><id>https://blog.miz-ar.info/2025/03/never-type/</id><title type="text">never型があると便利か（言語処理系実装者の観点から）</title><updated>2025-03-18T11:02:42+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2025/03/never-type/"/><summary type="html">TypeScriptをはじめとするいくつかのプログラミング言語には、never型という型がある。この型は典型的には「制御を返さない関数」の返り値として使われる： never型は型システム的には「値を持たない型」「任意の型 [&amp;#8230;]</summary></entry><entry><id>https://syocy.hatenablog.com/entry/2025/01/11/213514</id><title type="text">Haskellで雑にA/Bテストの検定</title><updated>2025-01-11T21:35:14+09:00</updated><author><name>syocy</name></author><link href="https://syocy.hatenablog.com/entry/2025/01/11/213514"/><summary type="html">年に一度くらいは Haskell で A/B テストの検定をしたくなるでしょう。普段は R とか Python とか表計算ソフトで済ますにしても人生時にはそのようなゆとりも必要です。 Haskell環境の準備 Haskellスクリプティング A/Bテストの設定 Haskellでカイ二乗検定 補足: chi2testの自由度引数の意味 参考文献 Haskell環境の準備 PC が吹っ飛んだので Haskell 環境がありません。まず Haskell 環境から準備します。 ……とは言っても GHCup を入れて質問にポチポチ回答するだけで GHC や Cabal や Stack や Haskell…</summary></entry><entry><id>https://blog.miz-ar.info/2024/12/my-contributions-to-ghc-2024/</id><title type="text">GHCへの私の貢献2024</title><updated>2024-12-24T01:34:44+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2024/12/my-contributions-to-ghc-2024/"/><summary type="html">この記事はHaskell Advent Calendar 2024の24日目の記事です。 私はここ数年、Haskellの主要な処理系であるGHCに趣味で貢献しています。この記事では、今年（2024年）行なった貢献を紹介し [&amp;#8230;]</summary></entry><entry><id>https://blog.miz-ar.info/2024/12/compile-time-constant/</id><title type="text">コンパイル時定数しか受け付けない引数</title><updated>2024-12-15T09:18:12+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2024/12/compile-time-constant/"/><summary type="html">普通のプログラミング言語の普通の関数は、実行時に決まる値を受け取ることができます。 これに対して、「コンパイル時に決まる値しか受け付けない引数」を表現できると便利な場面があるのではないかと思うことが最近ありました。 動機 [&amp;#8230;]</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2024/10/08/005209</id><title type="text">YAPC::Hakodate 2024 で様相論理について話してきました</title><updated>2024-10-09T00:18:34+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2024/10/08/005209"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された YAPC::Hakodate 2024 で、様相論理について登壇してきました。公募 CFP 枠です。 fortee.jp しばらく後に録画アーカイブも公開される予定です。 質問への回答 当日は、ありがたいことに会場で何名かの方が質問を出してくれました。回答をまとめておきます。 EG φ の検査アルゴリズムにおいて、φ が真になるような強連結成分が複数見つかった場合はどうするのか？ EG φ が真になるのは「その状態から始まって φ を満たし続ける無限パスが存在するとき」なので、そのようなパスが複数見つかっても真偽に影響はありません。 もし実装するの…</summary></entry><entry><id>https://kurokawh.blogspot.com/2024/07/thinkpad-trackpoint.html</id><title type="text">[ThinkPad] タッチパッド（trackpoint）の中央ボタンをマウスの中ボタンにアサインする方法</title><updated>2024-07-21T22:34:54.908+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2024/07/thinkpad-trackpoint.html"/><summary type="text">ThinkPadでタッチパッド（trackpoint）の中央ボタンをマウスの中ボタンにアサインする方法です。忘れそうなのでメモ。「設定」→「マウス」を開き「ELAN TrackPoint for ThinkTrackPoint」の「TrackPoint settings」を開く。開いた「ELAN TrackPoint for ThinkTrackPoint」の「中央ボタン」のリストボックすのデフォルトが「スクロール」になっている。これを「中ボタン」に変更すると、中ボタンクリック挙動になる。※ 公式ページ（リンク）では、「その他のマウスオプション」で表示されるダイアログに「ThankPad」タブが表示される、とあるが、2024.07.19現在、Windows10 22H2では表示されないので注意が必要。</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2024/05/25/204350</id><title type="text">#技術書典 16 で Go を使って #自作モデル検査器 をつくる本を頒布します</title><updated>2024-05-25T20:43:50+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2024/05/25/204350"/><summary type="html">こんにちは、チェシャ猫です。 今回、技術書典 16 にて、新刊『モデル検査器をつくる〜Goで実装して学ぶ形式手法〜』を頒布します。 techbookfest.org どんな本？ ただツールを使うだけの形式手法から、君の手でつくる形式手法へ。Go 言語でモデル検査器を実装しながら学ぼう！ 書名の通り、Go でモデル検査器を実装する本です。Pramo 言語と名づけた本書オリジナルのモデリング言語を定義し、その可視化器と検査器を作成します。 Pramo 言語は、ある種のマルチスレッドをサポートするプログラミング言語であり、Go の埋め込み DSL として記述されます。例えば有名な「食事する哲学者」は…</summary></entry><entry><id>https://blog.miz-ar.info/2024/05/techbookfest16/</id><title type="text">技術書典16に、Haskellでの型レベルプログラミングの本を出します</title><updated>2024-05-16T10:13:30+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2024/05/techbookfest16/"/><summary type="html">今度の5月26日（日）に池袋でオフライン開催される技術書典16に、サークル「だめぽラボ」で新刊「Haskellでの型レベルプログラミング」を出します。既刊も在庫があるものは頒布します。 技術書典16の基本的な情報は以下の [&amp;#8230;]</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2023/12/25/Haskell_%E3%81%A7_Open_Telemetry_%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6%E3%82%AA%E3%83%96%E3%82%B6%E3%83%BC%E3%83%90%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3%E3%83%BC%E3%82%92%E5%90%91%E4%B8%8A</id><title type="text">Haskell で Open Telemetry を利用してオブザーバビリティーを向上させよう</title><updated>2023-12-25T17:35:26+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2023/12/25/Haskell_%E3%81%A7_Open_Telemetry_%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6%E3%82%AA%E3%83%96%E3%82%B6%E3%83%BC%E3%83%90%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3%E3%83%BC%E3%82%92%E5%90%91%E4%B8%8A"/><summary type="html">Open Telemetry って何？ この記事では Open Telemetry のトレースの機能を使います。トレースを使うと、サーバーを越境してコールグラフとその実行時間などを取得することができます。下の画像は Jaeger のスクリーンショットです。Jaeger は Open Telemetry の規格にのっとったコレクター実装のひとつです。 この例では HTTP サーバーと HTTP クライアントでトレースを取得しています。まずサーバーが /1 のパスでリクエストを受けつけたことが分かります。このリクエストに対してレスポンスを返すまでに 845μs かかっていますね。このトレースにおけ…</summary></entry><entry><id>https://blog.miz-ar.info/2023/12/my-contributions-to-ghc/</id><title type="text">GHCへの私の貢献2023</title><updated>2023-12-05T22:00:00+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2023/12/my-contributions-to-ghc/"/><summary type="html">この記事は Haskell Advent Calendar 2023 の6日目の記事です。 私はここ数年、HaskellコンパイラーであるGHCに貢献しています。この記事では、今年（2023年）に私が行った貢献を紹介しま [&amp;#8230;]</summary></entry><entry><id>https://kurokawh.blogspot.com/2023/12/atok.html</id><title type="text">[ATOK] 候補ウィンドウがカーソル位置ではなく、画面中央に固定表示されるようになってしまった</title><updated>2023-12-05T12:07:55.681+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2023/12/atok.html"/><summary type="text">&amp;nbsp;[ATOK] 候補ウィンドウがカーソル位置ではなく、画面中央に固定表示されるようになってしまったWindows10上で、特に設定を変更したつもりはないのだが、変換候補ウィンドウ、及び、推測候補ウィンドウが画面中央に固定表示される状態になった。JUST SYSTEMSのサポートページに以下のページがあり、ウィンドウをドラッグ＆ドロップすることで位置を変更できることが分かったが、肝心の「左上のピン」が表示されておらず、カーソル位置表示に戻すことができない。	[サポートFAQ] 候補ウィンドウの表示位置を変更するATOKプロパティ設定の中を確認しても、表示・非表示の切り替えはあるが、表示位置の切り替えが見つからない･･･（FAQは2007年記載なので、古いバージョンの挙動っぽい）。困っていた中、ふと候補ウィンドウ右下の画面の「候補メニュー」の存在に気がつき、表示してみると「表示位置</summary></entry><entry><id>https://kurokawh.blogspot.com/2018/02/windows-windows10.html</id><title type="text">[windows] Windows10セットアップ・設定項目のメモ</title><updated>2023-10-02T19:40:04.272+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セットアップ時の設定項目、インストールアプリの備忘録。


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

タスクバーの設定&amp;nbsp;

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

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

タスクバーをすべての ディスプレイに表示する：オフシステムアイコンのオン／オフの切り替え
入力インジケーター： オフ


&amp;nbsp;Quick Launcherを表示する

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

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

「Windows 10」のコントロールパネルを表示する</summary></entry><entry><id>https://blog.miz-ar.info/2023/08/haskell-simd/</id><title type="text">Haskell/GHCのSIMDについて考える</title><updated>2023-08-17T13:35:53+00:00</updated><author><name>mod_poppo</name></author><link href="https://blog.miz-ar.info/2023/08/haskell-simd/"/><summary type="html">最近のコンピューターの性能を活用するには、何らかの並列化が必須です。具体的にはSIMDの活用やマルチコア（それとGPU）です。プログラミング言語でこれらを利用できれば「C言語よりも速い」を名乗れます。この記事では並列化技 [&amp;#8230;]</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2023/07/27/195634</id><title type="text">Developers Summit 2023 Summer でサーバーレスについて話してきました</title><updated>2023-07-27T19:56:34+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2023/07/27/195634"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された Developers Summit 2023 Summer で、サーバーレスコンピューティングの形式化について登壇してきました。公募 CFP 枠です。 event.shoeisha.jp 内容は Jangda et al. (2019) による論文 &#34;Formal Foundations of Serverless Computing&#34; を軸にしています。この論文はサーバーレスコンピューティングに対して操作的意味論の定式化を行うものであり、プログラミングの国際学会 OOPSLA &#39;19 の Distinguished Paper を受賞しています。…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2023/07/18/134910</id><title type="text">意地でも関心を分離する</title><updated>2023-07-18T13:49:10+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2023/07/18/134910"/><summary type="html">マイクロサービスアーキテクチャにおいて、ある構造化されたデータを、構造を維持したまま別のコンポーネントでも使いたくなる誘惑が存在する。 例えば、ドメインロジックを扱うコンポーネントに「ユーザーの種別（ゲスト、メンバー、管理者）」という概念があり、API トークンの認可情報に含めたいとして、APIトークンを管理するコンポーネントはその概念に関与すべきだろうか。 // 関与しない定義 IssueToken(userType: string, expiresAt: Date): Token // 関与する定義 enum UserType { Guest, Member, Admin, } Issue…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2023/06/08/175748</id><title type="text">リリースされていない変更が溜まるのを防ぐGitHub Action「tocenbough」</title><updated>2023-06-08T17:57:48+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2023/06/08/175748"/><summary type="html">チームでソフトウェア開発をするとき、一度のリリースに含まれる変更が多すぎることにより、動作検証に時間がかかったり、問題が発生した時の原因特定が難しくなることがある。これを防ぐため、tocenboughというGitHub Actionを作った。読み方はもちろん「とおせんぼう」だ。 github.com 内容は至ってシンプルで、前回のlatest releaseからのマージコミットの数を計算し、その数が閾値を上回ったら落ちるというだけのスクリプトである。かなり単純なので、動作を把握するにはソースを見てもらったほうが早いかもしれない。 # GitHubから最新のリリースのタグを取得する。これがプルリ…</summary></entry><entry><id>https://syocy.hatenablog.com/entry/2023/05/11/000226</id><title type="text">ローカルk8sの上に色んなサービスを立てて壊す</title><updated>2023-05-11T00:02:26+09:00</updated><author><name>syocy</name></author><link href="https://syocy.hatenablog.com/entry/2023/05/11/000226"/><summary type="html">ローカルに立ち上げた Kubernetes Dashboard モダンなサービス開発はとにかく入用のミドルウェアが多い。ちょっとしたものを作るだけで RDB と NoSQL とインメモリキャッシュと監視ダッシュボードが必要になってしまう。遠い記憶に RDB とキーバリューストアとキャッシュと検索とジョブキューをすべて MySQL にやらせていた牧歌的な時代もあったような気がするがもうそんな時代ではないのだった。 実際にサービスをデプロイする段ではなくローカルで開発するときにもそういったミドルウェアがないと開発自体が進まない。かと言って素の OS の上にミドルウェアを入れまくると設定ファイルディ…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2023/01/01/000317</id><title type="text">2022 年、アウトプットの思い出</title><updated>2023-01-01T00:03:17+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2023/01/01/000317"/><summary type="html">こんにちは、チェシャ猫です。2022 年中は大変お世話になりました。本記事では自分自身への備忘も兼ねて、本年度の対外的な発表についてまとめておこうと思います。 2019 年のスライド一挙公開、あるいは 2020 年の方針 - チェシャ猫の消滅定理 2021 年のアウトプットを全部一気に思い出す - チェシャ猫の消滅定理 2022 年の活動実績 2022 年の登壇は 3 件でした。うち（先着や抽選ではなく）CFP に応募して採択されたものは 2 件です。以前は頻繁に登壇していた LT の回数を今年はかなり控えていたこともあり、件数としては少ない水準となりました。 賢く「振り分ける」ための Top…</summary></entry><entry><id>https://syocy.hatenablog.com/entry/kiritanpo2022</id><title type="text">きりたんぽ鍋を作る</title><updated>2022-12-01T22:48:37+09:00</updated><author><name>syocy</name></author><link href="https://syocy.hatenablog.com/entry/kiritanpo2022"/><summary type="html">きりたんぽ鍋を作ります。 きりたんぽ鍋の具材 具材 きりたんぽ さいとうの比内地鶏スープ 鶏肉 ネギ ゴボウ マイタケ 糸コンニャク セリ 手順 鶏肉を手頃な大きさに切る。 鍋に水1200mlを張って火にかけ、鶏肉を水から煮始める。 ゴボウをささがきにしてボウルの水につける。 ゴボウをボウルから出して鍋に入れる。 比内地鶏スープを入れる。 沸騰したら糸コンニャクとマイタケを入れる。 20分ほど煮たらネギを入れる。 ネギに火が通ったあたりできりたんぽを入れる。 きりたんぽを煮る時間は好みで調節する(1～5分くらい?)。 最後にセリを投入する。湯気を通す程度でいい。 完成。 鶏肉とゴボウは水から …</summary></entry><entry><id>https://matsubara0507.github.io/posts/2022-12-01-octicons-for-elm.html</id><title type="text">Elm 用の Octicons パッケージを作る</title><updated>2022-12-01T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2022-12-01-octicons-for-elm.html"/></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2022/11/23/205855</id><title type="text">CloudNative Days Tokyo 2022 に「謎は全て解けた！ 安楽椅子探偵に捧げる AWS ネットワーク分析入門」というタイトルで登壇してきました</title><updated>2022-11-23T20:58:55+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2022/11/23/205855"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された CloudNative Days Tokyo 2022 で、SMT ソルバを用いた AWS のネットワーク検査機能、VPC Rechability Analyzer と VPC Network Access Analyzer について話してきました。公募 CFP 枠です。 イベントサイトにて録画も視聴可能です。 event.cloudnativedays.jp 今回の登壇は「事前録画を提出」「当日リモートで登壇」「現地で登壇」のいずれの方式が選択可能だったのですが、自分は現地で登壇しました。 現地参加者全員が一つの部屋に集まる Keynote では…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2022/11/10/185512</id><title type="text">AWS Dev Day 2022 Japan に「サーバーレスは操作的意味論の夢を見るか？」というタイトルで登壇してきました</title><updated>2022-11-10T18:55:12+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2022/11/10/185512"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された AWS Dev Day 2022 Japan で、サーバーレスコンピューティングの形式化について発表してきました。公募 CFP 枠です。 www.youtube.com github.com ちなみに会場は観葉植物が生い茂る Amazon 品川オフィスで、講演者向けには個室の楽屋が用意されており（滞在時間は講演直前の 15 分程度ですが）、全体的にとてもゴージャスな感じでした。配信設備も本格的でしたが、話す側としては照明が眩しくてやりづらかったです。 講演概要 AWS Lambda を初めとするサーバーレスコンピューティング基盤には、 複数の関数が…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2022/10/19/wd_%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%9F</id><title type="text">wd コマンドをリリースした</title><updated>2022-10-19T02:56:15+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2022/10/19/wd_%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%9F"/><summary type="html">wd コマンドって？ これがしたかった。 hoge path/to/dir foo bar って実行したら、ワーキングディレクトリーが path/to/dir で foo bar コマンドを実行してくれるような hoge コマンドない？— かずき (@kakkun61) 2022年8月11日 $ wd ディレクトリー コマンド オプション とすると「ディレクトリー」をワーキングディレクトリーにして「コマンド」を「オプション」付きで実行する。 pushd でもできるけど popd と合わせるとタイプ数が多かった。 インストール GitHub のリリースページに Windows・Linux・mac…</summary></entry><entry><id>https://haskell.jp/blog/posts/2022/disband_admins.html</id><title type="text">一般社団法人としてのHaskell-jp Admins解散のお知らせ</title><updated>2022-09-18T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/2022/disband_admins.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;hr /&gt;
&lt;p&gt;誠に残念ながら、一般社団法人としての日本&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;ユーザーグループ管理委員会（通称&lt;span class=&#34;ascii&#34;&gt;Haskell-jp Admins&lt;/span&gt;）は、去る&lt;span class=&#34;ascii&#34;&gt;2022&lt;/span&gt;年&lt;span class=&#34;ascii&#34;&gt;4&lt;/span&gt;月&lt;span class=&#34;ascii&#34;&gt;16&lt;/span&gt;日を以て解散しました。先日、解散後に必要な処理のほぼすべてが完了しましたので、遅くなってしまいましたが、改めてこちらで報告致します。&lt;/p&gt;
&lt;div id=&#34;table-of-contents-outer&#34;&gt;
&lt;div id=&#34;table-of-contents&#34;&gt;
&lt;div class=&#34;table-of-contents-title&#34;&gt;
Contents
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#背景&#34; title=&#34;背景&#34;&gt;背景&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#今後の活動&#34; title=&#34;今後の活動&#34;&gt;今後の活動&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#今後の連絡先&#34; title=&#34;今後の連絡先&#34;&gt;今後の連絡先&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id=&#34;背景&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#背景&#34; title=&#34;背景&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;背景&lt;/h1&gt;
&lt;p&gt;解散の背景を一言で申しますと、「お金がかかりすぎる上に、士気も下がってしまったから」です。設立前に調査した際、法人住民税のルールを誤解してしまったことで想定より費用がかさんだことや、当初活動の一環として掲げていた大規模なオフラインイベントが、現状のコロナ禍において難しく、その上、代表を含む社員自身の開催するモチベーションが下がってしまっていることを鑑みて、先般行われた第&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;期の社員総会で解散する事を合意しました。&lt;/p&gt;
&lt;h1 id=&#34;今後の活動&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#今後の活動&#34; title=&#34;今後の活動&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;今後の活動&lt;/h1&gt;
&lt;p&gt;「一般社団法人」という法人格を失ってしまったので、法律上必要な場面において「日本&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;ユーザーグループ管理委員会」という名前を使用することはできなくなってしまいました。それでもできる範囲内で、任意団体として今までどおりの活動を継続したいと思います。&lt;/p&gt;
&lt;p&gt;具体的には、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;プログラミング言語&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;に関するイベントの企画・開催・運営
&lt;ul&gt;
&lt;li&gt;任意団体として適宜実施します&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;haskell.jp&lt;/span&gt; ドメインの維持・管理
&lt;ul&gt;
&lt;li&gt;ひとまず、代表であった山本悠滋が個人として引き継ぐことにします&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://haskell.jp/signin-slack.html&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;Slack Workspace&lt;/span&gt;&lt;/a&gt;を始めとする、交流や情報共有を行う場の提供・管理・運営
&lt;ul&gt;
&lt;li&gt;こちらは引き続き行います&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;今後の連絡先&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#今後の連絡先&#34; title=&#34;今後の連絡先&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;今後の連絡先&lt;/h1&gt;
&lt;p&gt;こちらは&lt;a href=&#34;../about_admins.html&#34;&gt;設立時の記事&lt;/a&gt;から特に変更はありません。&lt;a href=&#34;../about_admins.html#今後の活動と連絡先&#34;&gt;該当するセクション&lt;/a&gt;をご覧ください。&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
                &lt;i class=&#34;glyphicon glyphicon-chevron-left&#34; aria-hidden=&#34;true&#34; style=&#34;margin-right: 5px;&#34;&gt;&lt;/i&gt;
                &lt;a href=&#34;/posts/2025/wai-sample.html&#34; lang=&#34;ja&#34;&gt;簡単なHaskellのみでServant並に高機能なライブラリーを作ろうとした振り返り&lt;/a&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/2021/text-mono-traversable.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;文字列型を抽象化するのにはmono-traversableパッケージがいいかも&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&gt;

</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2022/08/12/Windows_%E3%81%A7_Haskell_SDL2</id><title type="text">Windows で Haskell SDL2</title><updated>2022-08-12T23:57:51+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2022/08/12/Windows_%E3%81%A7_Haskell_SDL2"/><summary type="html">Hackage にある SDL2 ライブラリーを Windows で利用する方法のメモ。 hackage.haskell.org Haskell-jp の Slack の質問をきっかけに手元で試したことを思い出しながら書いている。 sdl2.cabal に下記の記述があるので C ライブラリーを事前にインストールする必要がある。 pkgconfig-depends: sdl2 &gt;= 2.0.6 今回は stack に附属する MSYS2 を利用する。 stack exec -- pacman -S mingw64/mingw-w64-x86_64-SDL2 でインストールできるはずだが、MSY…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2022/06/24/184435</id><title type="text">SendGridのEvent WebHookを検証する</title><updated>2022-06-24T18:44:35+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2022/06/24/184435"/><summary type="html">メール配信プラットフォームであるSendGridは、メールの到達状況などを、呼び出し元のアプリケーションにWebHookで伝えることができる。 sendgrid.kke.co.jp アプリケーションがSendGridからリクエストを受け取るには、当然インターネットからアクセスできるようにする必要があるが、何の考えもなしに開放してはセキュリティ的に不安だ。しかしご安心を、SendGridにはWebHookにデジタル署名をつける機能がある。本稿ではその使い方を紹介する。 まず、Mail Settingsから、Signed Event Webhook Requestsという項目に入る。画面のボタンを…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2022/05/26/%E9%87%8D%E3%81%AD%E7%9D%80%E3%81%97%E3%81%9F%E3%83%90%E3%83%BC%E3%83%93%E3%83%BC%E4%BA%BA%E5%BD%A2_in_Haskell</id><title type="text">重ね着したバービー人形 in Haskell</title><updated>2022-05-26T14:08:06+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2022/05/26/%E9%87%8D%E3%81%AD%E7%9D%80%E3%81%97%E3%81%9F%E3%83%90%E3%83%BC%E3%83%93%E3%83%BC%E4%BA%BA%E5%BD%A2_in_Haskell"/><summary type="html">うやむやで終わる記事なので事前にご了承ください。 前回のあらすじ （前回などないので探さなくていいです。） 高カインドデータ型（Higher-kinded Datatypes; HKD）というものがあります。 fumieval.hatenablog.com qiita.com 簡単に説明すると下記のようなデータ型 D があるとき data D = D { a :: A , b :: B } D の代わりに H のようなデータ型を作ると便利という発想です。 data H f = H { a :: f A , b :: f B } H Identity だと D と同じ意味になりますし、H May…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2022/05/09/113715</id><title type="text">依存関係と階層構造の軛</title><updated>2022-05-09T11:37:15+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2022/05/09/113715"/><summary type="html">21世紀現在のプログラミング言語において、モジュールという機能はほぼ必要不可欠である。ソースコードを分割し、明示的な依存関係を指定する仕組みであるモジュールは、以下のような様々な恩恵をもたらす。 インクリメンタルビルド: モジュールごとにコンパイル結果を保存し、変更されていない部分を再コンパイルするのを防ぐ。 内部の隠蔽: 実装の詳細を隠蔽し、モジュール外から触れないようにする。プログラムの見通しをよくしたり、不正な操作をする機会を減らす。 アーキテクチャの整理: モジュールは他のモジュールを参照できるが、原則として相互参照はしない。依存の向きを定めることで、適切な抽象化と、 それに基づいた実…</summary></entry><entry><id>https://syocy.hatenablog.com/entry/nix-haskell</id><title type="text">NixによるHaskell開発環境の構築</title><updated>2022-04-13T01:41:07+09:00</updated><author><name>syocy</name></author><link href="https://syocy.hatenablog.com/entry/nix-haskell"/><summary type="html">Nix package manager によって Haskell のスクリプティングおよびパッケージ開発の環境構築をしていく。 こいついつも環境構築してんな ここで触れられないこと Nix スクリプティング ちゃんとした開発 haskell-language-server の導入 パッケージの設定 高度な依存関係オーバーライド トラブルシューティング nix-shell の立ち上がりが遅い cabal run で cabal 自体の出力を無視したい Mac で nix-env -i が失敗する Mac で channel が消滅する こいついつも環境構築してんな 環境構築以外はブログに書くよう…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2022/04/07/181838</id><title type="text">株式会社HERPに転職しました</title><updated>2022-04-07T18:18:38+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2022/04/07/181838"/><summary type="html">GitHubのプロフィールを見た人などはもしかしたら気づいているかもしれないが、Tsuru Capital LLCを退職し、2022年2月16日よりHERPの正社員となった。HERPは、大まかに言えば採用活動を管理するプラットフォームを提供している。 きっかけ Tsuru CapitalはKospi(韓国株のインデックス)のデリバティブを半自動取引する企業で、Haskellを使っているというのが最大の特徴として知られる謎多き会社だ。2015年に入社し、2022年まで6年以上働いた。流石に同じ職場にずっといると経験が偏ってしまうし、感覚としても飽きがきたので転職を考えた。 また、ある時期からRu…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2022-03-05-haskell-servant-and-websocket.html</id><title type="text">Haskell Servant + WebSocket で非同期ジョブを作る</title><updated>2022-03-05T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2022-03-05-haskell-servant-and-websocket.html"/></entry><entry><id>https://matsubara0507.github.io/posts/2022-01-12-replace-ogimage.html</id><title type="text">GitHub の URL を自動で OGP 画像に置き換える</title><updated>2022-01-12T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2022-01-12-replace-ogimage.html"/></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2021/12/31/212410</id><title type="text">2021 年のアウトプットを全部一気に思い出す</title><updated>2021-12-31T21:24:10+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2021/12/31/212410"/><summary type="html">こんにちは、チェシャ猫です。2021 年中は大変お世話になりました。 今年もいくつか外部で発表を行いましたが、その中には登壇報告の形でこのブログに載せていなかったり、スライドとして公開していないものがあります。自分自身の記録も兼ねて、本記事では 2021 年のアウトプットを一覧としてアーカイブしておきたいと思います。 2021 年の活動実績 2021 年の登壇は 9 件でした。うち（先着や抽選ではなく）CFP に応募して採択されたものは 5 件 です。傾向として以前よりも LT の割合が少なくなり、比較的長尺の登壇がメインになりました。 CockroachDB から覗く型式手法の世界【CFP …</summary></entry><entry><id>https://haskell.jp/blog/posts/2021/text-mono-traversable.html</id><title type="text">文字列型を抽象化するのにはmono-traversableパッケージがいいかも</title><updated>2021-12-25T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/2021/text-mono-traversable.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;p&gt;この記事は&lt;a href=&#34;https://qiita.com/advent-calendar/2021/haskell&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Advent Calendar 2021&lt;/span&gt;&lt;/a&gt;の&lt;span class=&#34;ascii&#34;&gt;25&lt;/span&gt;日目の記事です。&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;のよく言われる問題点の一つとして、文字列型が下記のようによく使われるものだけで&lt;strong&gt;&lt;span class=&#34;ascii&#34;&gt;5&lt;/span&gt;種類&lt;/strong&gt;もある、という点があります&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;String&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;Strict&lt;/span&gt;な&lt;code&gt;Text&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;Lazy&lt;/span&gt;な&lt;code&gt;Text&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;Strict&lt;/span&gt;な&lt;code&gt;ByteString&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;Lazy&lt;/span&gt;な&lt;code&gt;ByteString&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;small&gt;（上記の頻繁に使われるもの以外にも、もっとあります）&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;それぞれ確かに使いどころが違うので、アプリケーションで使用する場合は場面に応じて使い分ければいいのですが、文字列を使ったライブラリーを開発する場合はなかなか悩ましいものがあります。内部で依存しているライブラリーが使用しているものがあれば、それをそのまま使うのが簡単で確実ですが、そうでない場合も多いでしょう。そこで本稿では文字列型を抽象化して扱いたい場合の手段として、&lt;a href=&#34;https://hackage.haskell.org/package/mono-traversable&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;mono-traversalbe&lt;/span&gt;パッケージ&lt;/a&gt;を検討したいと思います。&lt;/p&gt;
&lt;div id=&#34;table-of-contents-outer&#34;&gt;
&lt;div id=&#34;table-of-contents&#34;&gt;
&lt;div class=&#34;table-of-contents-title&#34;&gt;
Contents
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#mono-traversableパッケージの紹介&#34; title=&#34;mono-traversableパッケージの紹介&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージの紹介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#mono-traversableパッケージにおける型クラスのメソッドと各種文字列型向け関数の対応表&#34; title=&#34;mono-traversableパッケージにおける型クラスのメソッドと各種文字列型向け関数の対応表&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージにおける型クラスのメソッドと、各種文字列型向け関数の対応表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#パフォーマンスに関わる注意事項&#34; title=&#34;パフォーマンスに関わる注意事項&#34;&gt;⚠️パフォーマンスに関わる注意事項&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#事例-stringから相互変換できる型を抽象化する&#34; title=&#34;事例-stringから相互変換できる型を抽象化する&#34;&gt;事例&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; &lt;code&gt;String&lt;/code&gt;から相互変換できる型を抽象化する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#まとめ&#34; title=&#34;まとめ&#34;&gt;まとめ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id=&#34;mono-traversableパッケージの紹介&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#mono-traversableパッケージの紹介&#34; title=&#34;mono-traversableパッケージの紹介&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージの紹介&lt;/h1&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージは、名前のとおり&lt;code&gt;MonoTraversable&lt;/code&gt;や&lt;code&gt;MonoFoldable&lt;/code&gt;、&lt;code&gt;MonoFunctor&lt;/code&gt;といったおなじみの型クラスの名前に&lt;code&gt;Mono&lt;/code&gt;という接頭辞を付けた型クラスによって、多様なコンテナ型を抽象化してくれます。これらの型クラスはすべて、&lt;code&gt;ByteString&lt;/code&gt;や&lt;code&gt;Text&lt;/code&gt;のような、「要素として持てる値の型が&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;種類だけ」の型も対象にしているのが特徴です。&lt;span class=&#34;ascii&#34;&gt;Type Family&lt;/span&gt;を応用し、次のように型毎に要素の型を固定することで、そうした特徴を実現しています&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;family&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Element&lt;/span&gt; mono&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Element&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ByteString&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Word8&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-4&#34;&gt;&lt;a href=&#34;#cb1-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Element&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Char&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-5&#34;&gt;&lt;a href=&#34;#cb1-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Element&lt;/span&gt; [a] &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb1-6&#34;&gt;&lt;a href=&#34;#cb1-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-7&#34;&gt;&lt;a href=&#34;#cb1-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-8&#34;&gt;&lt;a href=&#34;#cb1-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-9&#34;&gt;&lt;a href=&#34;#cb1-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;MonoFunctor&lt;/span&gt; mono &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-10&#34;&gt;&lt;a href=&#34;#cb1-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;-- ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-11&#34;&gt;&lt;a href=&#34;#cb1-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;  omap ::&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Element&lt;/span&gt; mono &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Element&lt;/span&gt; mono) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; mono &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; mono&lt;/span&gt;
&lt;span id=&#34;cb1-12&#34;&gt;&lt;a href=&#34;#cb1-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-13&#34;&gt;&lt;a href=&#34;#cb1-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;MonoFunctor&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ByteString&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-14&#34;&gt;&lt;a href=&#34;#cb1-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  omap &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ByteString&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;map&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-15&#34;&gt;&lt;a href=&#34;#cb1-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-16&#34;&gt;&lt;a href=&#34;#cb1-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;MonoFunctor&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Text&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-17&#34;&gt;&lt;a href=&#34;#cb1-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  omap &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; Text.map&lt;/span&gt;
&lt;span id=&#34;cb1-18&#34;&gt;&lt;a href=&#34;#cb1-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-19&#34;&gt;&lt;a href=&#34;#cb1-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;MonoFunctor&lt;/span&gt; [a] &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-20&#34;&gt;&lt;a href=&#34;#cb1-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  omap &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;map&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;※&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージのソースから引用して少し改変しました。&lt;/p&gt;
&lt;p&gt;さらに、これまで紹介した&lt;code&gt;MonoTraversable&lt;/code&gt;や&lt;code&gt;MonoFoldable&lt;/code&gt;、&lt;code&gt;MonoFunctor&lt;/code&gt;に加えて、&lt;code&gt;SemiSequence&lt;/code&gt;や&lt;code&gt;IsSequence&lt;/code&gt;という型クラスで分解や構築に関わる操作&lt;small&gt;（例えば&lt;code&gt;cons&lt;/code&gt;や&lt;code&gt;break&lt;/code&gt;）&lt;/small&gt;などの他、&lt;small&gt;（今回は取り上げませんが）&lt;/small&gt;&lt;code&gt;SetContainer&lt;/code&gt;などの型クラスで&lt;code&gt;Map&lt;/code&gt;や&lt;code&gt;Set&lt;/code&gt;、&lt;code&gt;IntMap&lt;/code&gt;などの型まで抽象化してくれます。&lt;/p&gt;
&lt;p&gt;そこで次の節では、この&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージにおける型クラスを中心に、&lt;code&gt;Data.Text&lt;/code&gt;モジュールや&lt;code&gt;Data.ByteString&lt;/code&gt;モジュールにおける各関数が、どの型クラスに対するどの関数に対応するのか、まとめた表を作ってみました。&lt;/p&gt;
&lt;h1 id=&#34;mono-traversableパッケージにおける型クラスのメソッドと各種文字列型向け関数の対応表&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#mono-traversableパッケージにおける型クラスのメソッドと各種文字列型向け関数の対応表&#34; title=&#34;mono-traversableパッケージにおける型クラスのメソッドと各種文字列型向け関数の対応表&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージにおける型クラスのメソッドと、各種文字列型向け関数の対応表&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;ℹ️調査した&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージのバージョンは&lt;span class=&#34;ascii&#34;&gt;1.0.15.3&lt;/span&gt;です&lt;/li&gt;
&lt;li&gt;ℹ️原則として関数の名前しか見ていないので、実際には異なる用途かも知れません&lt;/li&gt;
&lt;li&gt;ℹ️&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージにある型クラスの他、&lt;span class=&#34;ascii&#34;&gt;base&lt;/span&gt;パッケージにある&lt;code&gt;Monoid&lt;/code&gt;、&lt;code&gt;Semigroup&lt;/code&gt;などのメソッドも調査対象に含めました&lt;/li&gt;
&lt;li&gt;ℹ️&lt;code&gt;String&lt;/code&gt;については&lt;span class=&#34;ascii&#34;&gt;base&lt;/span&gt;パッケージにある関数のみを対象にしていますが、&lt;code&gt;Data.List&lt;/code&gt;モジュールのドキュメントと自分の記憶を頼りに埋めているので間違いがあるかも知れません&lt;/li&gt;
&lt;li&gt;ℹ️&lt;code&gt;Text&lt;/code&gt;・&lt;code&gt;ByteString&lt;/code&gt;については&lt;span class=&#34;ascii&#34;&gt;Strict&lt;/span&gt;なバージョンのドキュメントのみ参照しています。&lt;span class=&#34;ascii&#34;&gt;Lazy&lt;/span&gt;な方になかったらごめんなさい！&lt;/li&gt;
&lt;li&gt;ℹ️&lt;code&gt;Textual&lt;/code&gt;型クラスについては、&lt;code&gt;ByteString&lt;/code&gt;がインスタンスになっていないのでご注意ください&lt;/li&gt;
&lt;li&gt;ℹ️以下のような関数は除外しました&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IO&lt;/code&gt;が絡むもの&lt;/li&gt;
&lt;li&gt;プリミティブな処理で使うもの&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col style=&#34;width: 19%&#34; /&gt;
&lt;col style=&#34;width: 19%&#34; /&gt;
&lt;col style=&#34;width: 23%&#34; /&gt;
&lt;col style=&#34;width: 37%&#34; /&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;Text&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;ByteString&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;String&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;(&lt;/span&gt;&lt;code&gt;[Char]&lt;/code&gt;&lt;span class=&#34;ascii&#34;&gt;)&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;型クラス &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; 関数&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;oall&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;any&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;any&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;any&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;oany&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;append&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;append&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;++&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Semigroup&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;breakByte&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;breakEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;breakOnAll&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;breakOnEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;breakOn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;breakSubstring&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;break&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;break&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;break&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;break&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;center&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chunksOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;commonPrefixes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;compareLength&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;concatMap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;concatMap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;ofoldMap&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;ofold&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cons&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cons&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SemiSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;cons&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;copy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;copy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dropAround&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dropEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;dropEnd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dropWhileEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dropWhileEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dropWhileEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dropWhile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dropWhile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dropWhile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;dropWhile&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;drop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;drop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;drop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;drop&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;elemIndexEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;elemIndex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;elemIndex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;elemIndices&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;elemIndices&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;elem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;elem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;oelem&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;empty&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;empty&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&#34;&#34;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Monoid&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;mempty&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;filter&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;findIndexEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;findIndex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;findIndex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;findIndex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;findIndices&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;findIndices&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;findSubstring&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;findSubstrings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;find&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;find&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SemiSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;find&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;foldl&#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldl&#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldl&#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;ofoldl&#39;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;foldl1&#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldl1&#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldl1&#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;ofoldl1Ex&#39;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;foldl1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldl1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldl1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;foldl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldr&#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldr1&#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;foldr1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldr1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldr1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;ofoldr1Ex&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;foldr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foldr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;ofoldr&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;groupBy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;groupBy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;groupBy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;groupBy&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;group&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;group&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;group&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;group&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;head&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;head&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;head&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;headEx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;index&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;index&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;index&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;indexEx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;initEx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;inits&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;inits&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;inits&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;intercalate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;intercalate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;intercalate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;ointercalate&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;intersperse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;intersperse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;intersperse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SemiSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;intersperse&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isInfixOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;isInfixOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;isInfixOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;isInfixOf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isPrefixOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;isPrefixOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;isPrefixOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;isPrefixOf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isSuffixOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;isSuffixOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;isSuffixOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;isSuffixOf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;justifyLeft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;justifyRight&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;last&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;last&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;last&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;lastEx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;length&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;length&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;length&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;olength&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lines&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lines&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Textual&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;lines&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mapAccumL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mapAccumL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mapAccumL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mapAccumR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mapAccumR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mapAccumR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFunctor&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;omap&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;maximum&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;maximum&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;maximum&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;maximumEx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;minimum&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;minimum&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;minimum&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;minimumEx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;notElem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;notElem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;onotElem&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;onull&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pack&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pack&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsString&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;fromString&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;partition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;partition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;partition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;partition&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;replace&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;replaceSeq&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;replicate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;replicate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;replicate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;replicate&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reverse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reverse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reverse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SemiSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;reverse&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scanl1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scanl1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scanl1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scanl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scanl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scanl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scanr1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scanr1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scanr1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scanr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scanr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scanr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;singleton&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;singleton&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;singleton&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoPointed&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;opoint&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;snoc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;snoc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;snoc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SemiSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;snoc&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sort&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sort&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SemiSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;sort&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;spanEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;span&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;span&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;span&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SemiSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;span&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;splitAt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;splitAt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;splitAt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;splitAt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;splitOn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;splitOn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;splitSeq&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;splitWith&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;splitElem&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;split&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;splitWith&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;splitWhen&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;stripEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;N/A&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;stripPrefix&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;stripPrefix&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;stripPrefix&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;stripPrefix&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;stripStart&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;stripSuffix&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;stripSuffix&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;stripSuffix&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;strip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;tail&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tails&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tails&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tails&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;takeEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;takeWhileEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;takeWhileEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;takeWhile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;takeWhile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;takeWhile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;takeWhile&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;take&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;take&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;take&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;take&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;toCaseFold&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Textual&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;toCaseFold&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;toLower&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Textual&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;toLower&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;toTitle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;toUpper&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Textual&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;toUpper&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;transpose&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;transpose&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uncons&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uncons&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IsSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;uncons&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unfoldrN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unfoldrN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unfoldr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unfoldr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unfoldr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unlines&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unlines&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Textual&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;unlines&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unpack&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unpack&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoFoldable&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;otoList&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unsnoc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unsnoc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;N/A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SemiSequence&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;unsnoc&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unwords&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unwords&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Textual&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;unwords&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;words&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;words&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Textual&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;words&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zipWith&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;zipWith&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;zipWith&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoZip&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;ozipWith&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;zip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;zip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MonoZip&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;ozip&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!--
元ネタとして`:browse`した結果をメモしておきます

&gt; :browse Data.Text
T.all :: (Char -&gt; Bool) -&gt; T.Text -&gt; Bool
T.any :: (Char -&gt; Bool) -&gt; T.Text -&gt; Bool
T.append :: T.Text -&gt; T.Text -&gt; T.Text
T.break :: (Char -&gt; Bool) -&gt; T.Text -&gt; (T.Text, T.Text)
T.breakOn :: T.Text -&gt; T.Text -&gt; (T.Text, T.Text)
T.breakOnAll :: T.Text -&gt; T.Text -&gt; [(T.Text, T.Text)]
T.breakOnEnd :: T.Text -&gt; T.Text -&gt; (T.Text, T.Text)
T.center :: Int -&gt; Char -&gt; T.Text -&gt; T.Text
T.chunksOf :: Int -&gt; T.Text -&gt; [T.Text]
T.commonPrefixes ::
  T.Text -&gt; T.Text -&gt; Maybe (T.Text, T.Text, T.Text)
T.compareLength :: T.Text -&gt; Int -&gt; Ordering
T.concat :: [T.Text] -&gt; T.Text
T.concatMap :: (Char -&gt; T.Text) -&gt; T.Text -&gt; T.Text
T.cons :: Char -&gt; T.Text -&gt; T.Text
T.copy :: T.Text -&gt; T.Text
T.count :: T.Text -&gt; T.Text -&gt; Int
T.drop :: Int -&gt; T.Text -&gt; T.Text
T.dropAround :: (Char -&gt; Bool) -&gt; T.Text -&gt; T.Text
T.dropEnd :: Int -&gt; T.Text -&gt; T.Text
T.dropWhile :: (Char -&gt; Bool) -&gt; T.Text -&gt; T.Text
T.dropWhileEnd :: (Char -&gt; Bool) -&gt; T.Text -&gt; T.Text
T.filter :: (Char -&gt; Bool) -&gt; T.Text -&gt; T.Text
T.find :: (Char -&gt; Bool) -&gt; T.Text -&gt; Maybe Char
T.findIndex :: (Char -&gt; Bool) -&gt; T.Text -&gt; Maybe Int
T.foldl :: (a -&gt; Char -&gt; a) -&gt; a -&gt; T.Text -&gt; a
T.foldl&#39; :: (a -&gt; Char -&gt; a) -&gt; a -&gt; T.Text -&gt; a
T.foldl1 :: (Char -&gt; Char -&gt; Char) -&gt; T.Text -&gt; Char
T.foldl1&#39; :: (Char -&gt; Char -&gt; Char) -&gt; T.Text -&gt; Char
T.foldr :: (Char -&gt; a -&gt; a) -&gt; a -&gt; T.Text -&gt; a
T.foldr1 :: (Char -&gt; Char -&gt; Char) -&gt; T.Text -&gt; Char
T.group :: T.Text -&gt; [T.Text]
T.groupBy :: (Char -&gt; Char -&gt; Bool) -&gt; T.Text -&gt; [T.Text]
T.head :: T.Text -&gt; Char
T.index :: T.Text -&gt; Int -&gt; Char
T.init :: T.Text -&gt; T.Text
T.inits :: T.Text -&gt; [T.Text]
T.intercalate :: T.Text -&gt; [T.Text] -&gt; T.Text
T.intersperse :: Char -&gt; T.Text -&gt; T.Text
T.isInfixOf :: T.Text -&gt; T.Text -&gt; Bool
T.isPrefixOf :: T.Text -&gt; T.Text -&gt; Bool
T.isSuffixOf :: T.Text -&gt; T.Text -&gt; Bool
T.justifyLeft :: Int -&gt; Char -&gt; T.Text -&gt; T.Text
T.justifyRight :: Int -&gt; Char -&gt; T.Text -&gt; T.Text
T.last :: T.Text -&gt; Char
T.length :: T.Text -&gt; Int
T.lines :: T.Text -&gt; [T.Text]
T.map :: (Char -&gt; Char) -&gt; T.Text -&gt; T.Text
T.mapAccumL ::
  (a -&gt; Char -&gt; (a, Char)) -&gt; a -&gt; T.Text -&gt; (a, T.Text)
T.mapAccumR ::
  (a -&gt; Char -&gt; (a, Char)) -&gt; a -&gt; T.Text -&gt; (a, T.Text)
T.maximum :: T.Text -&gt; Char
T.minimum :: T.Text -&gt; Char
T.null :: T.Text -&gt; Bool
T.pack :: String -&gt; T.Text
T.partition :: (Char -&gt; Bool) -&gt; T.Text -&gt; (T.Text, T.Text)
T.replace :: T.Text -&gt; T.Text -&gt; T.Text -&gt; T.Text
T.replicate :: Int -&gt; T.Text -&gt; T.Text
T.reverse :: T.Text -&gt; T.Text
T.scanl :: (Char -&gt; Char -&gt; Char) -&gt; Char -&gt; T.Text -&gt; T.Text
T.scanl1 :: (Char -&gt; Char -&gt; Char) -&gt; T.Text -&gt; T.Text
T.scanr :: (Char -&gt; Char -&gt; Char) -&gt; Char -&gt; T.Text -&gt; T.Text
T.scanr1 :: (Char -&gt; Char -&gt; Char) -&gt; T.Text -&gt; T.Text
T.snoc :: T.Text -&gt; Char -&gt; T.Text
T.span :: (Char -&gt; Bool) -&gt; T.Text -&gt; (T.Text, T.Text)
T.split :: (Char -&gt; Bool) -&gt; T.Text -&gt; [T.Text]
T.splitAt :: Int -&gt; T.Text -&gt; (T.Text, T.Text)
T.splitOn :: T.Text -&gt; T.Text -&gt; [T.Text]
T.strip :: T.Text -&gt; T.Text
T.stripEnd :: T.Text -&gt; T.Text
T.stripPrefix :: T.Text -&gt; T.Text -&gt; Maybe T.Text
T.stripStart :: T.Text -&gt; T.Text
T.stripSuffix :: T.Text -&gt; T.Text -&gt; Maybe T.Text
T.tail :: T.Text -&gt; T.Text
T.tails :: T.Text -&gt; [T.Text]
T.take :: Int -&gt; T.Text -&gt; T.Text
T.takeEnd :: Int -&gt; T.Text -&gt; T.Text
T.takeWhile :: (Char -&gt; Bool) -&gt; T.Text -&gt; T.Text
T.takeWhileEnd :: (Char -&gt; Bool) -&gt; T.Text -&gt; T.Text
T.toCaseFold :: T.Text -&gt; T.Text
T.toLower :: T.Text -&gt; T.Text
T.toTitle :: T.Text -&gt; T.Text
T.toUpper :: T.Text -&gt; T.Text
T.transpose :: [T.Text] -&gt; [T.Text]
T.uncons :: T.Text -&gt; Maybe (Char, T.Text)
T.unfoldr :: (a -&gt; Maybe (Char, a)) -&gt; a -&gt; T.Text
T.unfoldrN :: Int -&gt; (a -&gt; Maybe (Char, a)) -&gt; a -&gt; T.Text
T.unlines :: [T.Text] -&gt; T.Text
T.unsnoc :: T.Text -&gt; Maybe (T.Text, Char)
T.unwords :: [T.Text] -&gt; T.Text
T.words :: T.Text -&gt; [T.Text]
T.zip :: T.Text -&gt; T.Text -&gt; [(Char, Char)]
T.zipWith :: (Char -&gt; Char -&gt; Char) -&gt; T.Text -&gt; T.Text -&gt; T.Text
type T.Text :: *
data T.Text
  = Data.Text.Internal.Text {-# UNPACK #-}Data.Text.Array.Array
                            {-# UNPACK #-}Int
                            {-# UNPACK #-}Int
T.empty :: T.Text
T.singleton :: Char -&gt; T.Text
T.unpack :: T.Text -&gt; String
T.unpackCString# :: GHC.Prim.Addr# -&gt; T.Text

B.all :: (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; Bool
B.any :: (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; Bool
B.append :: B.ByteString -&gt; B.ByteString -&gt; B.ByteString
B.appendFile :: FilePath -&gt; B.ByteString -&gt; IO ()
B.break ::
  (GHC.Word.Word8 -&gt; Bool)
  -&gt; B.ByteString -&gt; (B.ByteString, B.ByteString)
B.breakByte ::
  GHC.Word.Word8 -&gt; B.ByteString -&gt; (B.ByteString, B.ByteString)
B.breakEnd ::
  (GHC.Word.Word8 -&gt; Bool)
  -&gt; B.ByteString -&gt; (B.ByteString, B.ByteString)
B.breakSubstring ::
  B.ByteString -&gt; B.ByteString -&gt; (B.ByteString, B.ByteString)
B.concat :: [B.ByteString] -&gt; B.ByteString
B.concatMap ::
  (GHC.Word.Word8 -&gt; B.ByteString) -&gt; B.ByteString -&gt; B.ByteString
B.cons :: GHC.Word.Word8 -&gt; B.ByteString -&gt; B.ByteString
B.copy :: B.ByteString -&gt; B.ByteString
B.count :: GHC.Word.Word8 -&gt; B.ByteString -&gt; Int
B.drop :: Int -&gt; B.ByteString -&gt; B.ByteString
B.dropWhile ::
  (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; B.ByteString
B.dropWhileEnd ::
  (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; B.ByteString
B.elem :: GHC.Word.Word8 -&gt; B.ByteString -&gt; Bool
B.elemIndex :: GHC.Word.Word8 -&gt; B.ByteString -&gt; Maybe Int
B.elemIndexEnd :: GHC.Word.Word8 -&gt; B.ByteString -&gt; Maybe Int
B.elemIndices :: GHC.Word.Word8 -&gt; B.ByteString -&gt; [Int]
B.empty :: B.ByteString
B.filter ::
  (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; B.ByteString
B.find ::
  (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; Maybe GHC.Word.Word8
B.findIndex ::
  (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; Maybe Int
B.findIndexEnd ::
  (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; Maybe Int
B.findIndices :: (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; [Int]
B.findSubstring :: B.ByteString -&gt; B.ByteString -&gt; Maybe Int
B.findSubstrings :: B.ByteString -&gt; B.ByteString -&gt; [Int]
B.foldl :: (a -&gt; GHC.Word.Word8 -&gt; a) -&gt; a -&gt; B.ByteString -&gt; a
B.foldl&#39; :: (a -&gt; GHC.Word.Word8 -&gt; a) -&gt; a -&gt; B.ByteString -&gt; a
B.foldl1 ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; GHC.Word.Word8)
  -&gt; B.ByteString -&gt; GHC.Word.Word8
B.foldl1&#39; ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; GHC.Word.Word8)
  -&gt; B.ByteString -&gt; GHC.Word.Word8
B.foldr :: (GHC.Word.Word8 -&gt; a -&gt; a) -&gt; a -&gt; B.ByteString -&gt; a
B.foldr&#39; :: (GHC.Word.Word8 -&gt; a -&gt; a) -&gt; a -&gt; B.ByteString -&gt; a
B.foldr1 ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; GHC.Word.Word8)
  -&gt; B.ByteString -&gt; GHC.Word.Word8
B.foldr1&#39; ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; GHC.Word.Word8)
  -&gt; B.ByteString -&gt; GHC.Word.Word8
B.getContents :: IO B.ByteString
B.getLine :: IO B.ByteString
B.group :: B.ByteString -&gt; [B.ByteString]
B.groupBy ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; Bool)
  -&gt; B.ByteString -&gt; [B.ByteString]
B.hGet :: GHC.IO.Handle.Types.Handle -&gt; Int -&gt; IO B.ByteString
B.hGetContents :: GHC.IO.Handle.Types.Handle -&gt; IO B.ByteString
B.hGetLine :: GHC.IO.Handle.Types.Handle -&gt; IO B.ByteString
B.hGetNonBlocking ::
  GHC.IO.Handle.Types.Handle -&gt; Int -&gt; IO B.ByteString
B.hGetSome :: GHC.IO.Handle.Types.Handle -&gt; Int -&gt; IO B.ByteString
B.hPut :: GHC.IO.Handle.Types.Handle -&gt; B.ByteString -&gt; IO ()
B.hPutNonBlocking ::
  GHC.IO.Handle.Types.Handle -&gt; B.ByteString -&gt; IO B.ByteString
B.hPutStr :: GHC.IO.Handle.Types.Handle -&gt; B.ByteString -&gt; IO ()
B.hPutStrLn :: GHC.IO.Handle.Types.Handle -&gt; B.ByteString -&gt; IO ()
B.head :: B.ByteString -&gt; GHC.Word.Word8
B.index :: B.ByteString -&gt; Int -&gt; GHC.Word.Word8
B.init :: B.ByteString -&gt; B.ByteString
B.inits :: B.ByteString -&gt; [B.ByteString]
B.interact :: (B.ByteString -&gt; B.ByteString) -&gt; IO ()
B.intercalate :: B.ByteString -&gt; [B.ByteString] -&gt; B.ByteString
B.intersperse :: GHC.Word.Word8 -&gt; B.ByteString -&gt; B.ByteString
B.isInfixOf :: B.ByteString -&gt; B.ByteString -&gt; Bool
B.isPrefixOf :: B.ByteString -&gt; B.ByteString -&gt; Bool
B.isSuffixOf :: B.ByteString -&gt; B.ByteString -&gt; Bool
B.last :: B.ByteString -&gt; GHC.Word.Word8
B.length :: B.ByteString -&gt; Int
B.map ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8) -&gt; B.ByteString -&gt; B.ByteString
B.mapAccumL ::
  (acc -&gt; GHC.Word.Word8 -&gt; (acc, GHC.Word.Word8))
  -&gt; acc -&gt; B.ByteString -&gt; (acc, B.ByteString)
B.mapAccumR ::
  (acc -&gt; GHC.Word.Word8 -&gt; (acc, GHC.Word.Word8))
  -&gt; acc -&gt; B.ByteString -&gt; (acc, B.ByteString)
B.maximum :: B.ByteString -&gt; GHC.Word.Word8
B.minimum :: B.ByteString -&gt; GHC.Word.Word8
B.notElem :: GHC.Word.Word8 -&gt; B.ByteString -&gt; Bool
B.null :: B.ByteString -&gt; Bool
B.pack :: [GHC.Word.Word8] -&gt; B.ByteString
B.packCString :: Foreign.C.String.CString -&gt; IO B.ByteString
B.packCStringLen :: Foreign.C.String.CStringLen -&gt; IO B.ByteString
B.partition ::
  (GHC.Word.Word8 -&gt; Bool)
  -&gt; B.ByteString -&gt; (B.ByteString, B.ByteString)
B.putStr :: B.ByteString -&gt; IO ()
B.putStrLn :: B.ByteString -&gt; IO ()
B.readFile :: FilePath -&gt; IO B.ByteString
B.replicate :: Int -&gt; GHC.Word.Word8 -&gt; B.ByteString
B.reverse :: B.ByteString -&gt; B.ByteString
B.scanl ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; GHC.Word.Word8)
  -&gt; GHC.Word.Word8 -&gt; B.ByteString -&gt; B.ByteString
B.scanl1 ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; GHC.Word.Word8)
  -&gt; B.ByteString -&gt; B.ByteString
B.scanr ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; GHC.Word.Word8)
  -&gt; GHC.Word.Word8 -&gt; B.ByteString -&gt; B.ByteString
B.scanr1 ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; GHC.Word.Word8)
  -&gt; B.ByteString -&gt; B.ByteString
B.singleton :: GHC.Word.Word8 -&gt; B.ByteString
B.snoc :: B.ByteString -&gt; GHC.Word.Word8 -&gt; B.ByteString
B.sort :: B.ByteString -&gt; B.ByteString
B.span ::
  (GHC.Word.Word8 -&gt; Bool)
  -&gt; B.ByteString -&gt; (B.ByteString, B.ByteString)
B.spanEnd ::
  (GHC.Word.Word8 -&gt; Bool)
  -&gt; B.ByteString -&gt; (B.ByteString, B.ByteString)
B.split :: GHC.Word.Word8 -&gt; B.ByteString -&gt; [B.ByteString]
B.splitAt :: Int -&gt; B.ByteString -&gt; (B.ByteString, B.ByteString)
B.splitWith ::
  (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; [B.ByteString]
B.stripPrefix :: B.ByteString -&gt; B.ByteString -&gt; Maybe B.ByteString
B.stripSuffix :: B.ByteString -&gt; B.ByteString -&gt; Maybe B.ByteString
B.tail :: B.ByteString -&gt; B.ByteString
B.tails :: B.ByteString -&gt; [B.ByteString]
B.take :: Int -&gt; B.ByteString -&gt; B.ByteString
B.takeWhile ::
  (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; B.ByteString
B.takeWhileEnd ::
  (GHC.Word.Word8 -&gt; Bool) -&gt; B.ByteString -&gt; B.ByteString
B.transpose :: [B.ByteString] -&gt; [B.ByteString]
B.uncons :: B.ByteString -&gt; Maybe (GHC.Word.Word8, B.ByteString)
B.unfoldr :: (a -&gt; Maybe (GHC.Word.Word8, a)) -&gt; a -&gt; B.ByteString
B.unfoldrN ::
  Int
  -&gt; (a -&gt; Maybe (GHC.Word.Word8, a)) -&gt; a -&gt; (B.ByteString, Maybe a)
B.unpack :: B.ByteString -&gt; [GHC.Word.Word8]
B.unsnoc :: B.ByteString -&gt; Maybe (B.ByteString, GHC.Word.Word8)
B.unzip ::
  [(GHC.Word.Word8, GHC.Word.Word8)] -&gt; (B.ByteString, B.ByteString)
B.useAsCString ::
  B.ByteString -&gt; (Foreign.C.String.CString -&gt; IO a) -&gt; IO a
B.useAsCStringLen ::
  B.ByteString -&gt; (Foreign.C.String.CStringLen -&gt; IO a) -&gt; IO a
B.writeFile :: FilePath -&gt; B.ByteString -&gt; IO ()
B.zip ::
  B.ByteString -&gt; B.ByteString -&gt; [(GHC.Word.Word8, GHC.Word.Word8)]
B.zipWith ::
  (GHC.Word.Word8 -&gt; GHC.Word.Word8 -&gt; a)
  -&gt; B.ByteString -&gt; B.ByteString -&gt; [a]
type B.ByteString :: *
data B.ByteString
  = Data.ByteString.Internal.PS {-# UNPACK #-}(GHC.ForeignPtr.ForeignPtr
                                                 GHC.Word.Word8)
                                {-# UNPACK #-}Int
                                {-# UNPACK #-}Int
--&gt;
&lt;p&gt;以上です。残念ながら万能とはいかないようで、いくつか「&lt;span class=&#34;ascii&#34;&gt;N/A&lt;/span&gt;」、すなわち対応するものがない関数もありますが、他の関数の組み合わせで実装できるものもあるでしょう。&lt;/p&gt;
&lt;h1 id=&#34;パフォーマンスに関わる注意事項&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#パフォーマンスに関わる注意事項&#34; title=&#34;パフォーマンスに関わる注意事項&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;⚠️パフォーマンスに関わる注意事項&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;MonoTraversable&lt;/code&gt;などに限らず、型クラスを使って関数を多相化したとき全般に言えることですが、コンパイル時にインスタンスの解決が行えなかった場合、直接対象の型の相当する関数を呼ぶより少し遅くなってしまう場合があります（&lt;a href=&#34;https://blog.miz-ar.info/2016/06/writing-efficient-program-with-haskell/#2.specialization&#34;&gt;参考&lt;/a&gt;）。&lt;/p&gt;
&lt;p&gt;また、それに限らず、各型クラスのメソッドでない関数は、各型の相当する関数でオーバーライドできないため、効率の悪い処理になってしまう恐れがあります。例えば、&lt;a href=&#34;https://hackage.haskell.org/package/mono-traversable-1.0.15.3/docs/src/Data.MonoTraversable.html#ointercalate&#34;&gt;&lt;code&gt;ointercalate&lt;/code&gt;関数&lt;/a&gt;の実装を見ると、&lt;code&gt;Text&lt;/code&gt;や&lt;code&gt;ByteString&lt;/code&gt;などについては&lt;code&gt;RULES&lt;/code&gt;プラグマで最適な実装を設定しているようですが、それ以外の型については一旦リストに変換してから結合する、という効率の悪そうな処理をしています。&lt;/p&gt;
&lt;h1 id=&#34;事例-stringから相互変換できる型を抽象化する&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#事例-stringから相互変換できる型を抽象化する&#34; title=&#34;事例-stringから相互変換できる型を抽象化する&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;事例&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; &lt;code&gt;String&lt;/code&gt;から相互変換できる型を抽象化する&lt;/h1&gt;
&lt;p&gt;最後に、最近私が作った（まだリリースしてない）ライブラリーにおいて、&lt;code&gt;MonoFoldable&lt;/code&gt;と&lt;code&gt;IsString&lt;/code&gt;を使うことで、&lt;code&gt;Text&lt;/code&gt;と&lt;code&gt;String&lt;/code&gt;両方をサポートした関数を紹介しておきます。ただ、時間とやる気パワーが残り少なくなってしまったので、該当の箇所だけ&lt;a href=&#34;https://github.com/igrep/envparse-applicative/blob/0fb7b23e45a09b4f53406b46bd563312ed27f2a4/src/EnvParse/Applicative.hs#L156&#34;&gt;こちら&lt;/a&gt;からコピペして、説明は簡単にしておきます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;stringVal ::&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;IsString&lt;/span&gt; a, &lt;span class=&#34;dt&#34;&gt;MT.MonoFoldable&lt;/span&gt; a, &lt;span class=&#34;dt&#34;&gt;MT.Element&lt;/span&gt; a &lt;span class=&#34;op&#34;&gt;~&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Char&lt;/span&gt;) &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CodecEnvVal&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;stringVal &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; valByFunction &lt;span class=&#34;dt&#34;&gt;CodecEnvValByFunction&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  { encode &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; MT.otoList&lt;/span&gt;
&lt;span id=&#34;cb2-4&#34;&gt;&lt;a href=&#34;#cb2-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  , decode &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Right&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; fromString&lt;/span&gt;
&lt;span id=&#34;cb2-5&#34;&gt;&lt;a href=&#34;#cb2-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;CodecEnvVal a&lt;/code&gt;型は、&lt;code&gt;a&lt;/code&gt;型を&lt;code&gt;String&lt;/code&gt;型と相互変換するための情報を含んだ型です。&lt;code&gt;stringVal&lt;/code&gt;の場合、名前のとおり文字列っぽい型と&lt;code&gt;String&lt;/code&gt;との相互変換ができなければなりません。もちろん単純に&lt;code&gt;String&lt;/code&gt;型だけをサポートして&lt;code&gt;Text&lt;/code&gt;用には別途&lt;code&gt;CodecEnvVal Text&lt;/code&gt;を作ってもいいのですが、一つの&lt;code&gt;CodecEnvVal a&lt;/code&gt;だけで扱えた方が楽でしょうし、今回は&lt;code&gt;MonoFoldable&lt;/code&gt;の&lt;code&gt;otoList&lt;/code&gt;と&lt;code&gt;IsString&lt;/code&gt;の&lt;code&gt;fromString&lt;/code&gt;を使って両方をサポートすることにしました。なお、これでは&lt;code&gt;ByteString&lt;/code&gt;がサポートできませんが、ここで相互変換する&lt;code&gt;String&lt;/code&gt;は、要件上人間が読み書きするファイルにおける文字列を想定しているので、&lt;code&gt;ByteString&lt;/code&gt;はバイナリーデータにだけ使うべきだ、という立場から敢えてサポートしていません。&lt;/p&gt;
&lt;h1 id=&#34;まとめ&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#まとめ&#34; title=&#34;まとめ&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;まとめ&lt;/h1&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;パッケージをうまく使えば、自前で専用の型クラスを作らなくても&lt;code&gt;String&lt;/code&gt;・&lt;code&gt;Text&lt;/code&gt;・&lt;code&gt;ByteString&lt;/code&gt;などを一挙にサポートする関数が書けるかも知れません！&lt;/p&gt;
&lt;p&gt;それでは&lt;span class=&#34;ascii&#34;&gt;2022&lt;/span&gt;年は&lt;span class=&#34;ascii&#34;&gt;mono-traversable&lt;/span&gt;で&lt;span class=&#34;ascii&#34;&gt;Happy Haskell String Programming!&lt;/span&gt;🚝&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
                &lt;i class=&#34;glyphicon glyphicon-chevron-left&#34; aria-hidden=&#34;true&#34; style=&#34;margin-right: 5px;&#34;&gt;&lt;/i&gt;
                &lt;a href=&#34;/posts/2022/disband_admins.html&#34; lang=&#34;ja&#34;&gt;一般社団法人としてのHaskell-jp Admins解散のお知らせ&lt;/a&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/2021/symbols-in-ghc.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;Haskellにおける記号の調べ方&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&gt;

</summary></entry><entry><id>https://haskell.jp/blog/posts/2021/symbols-in-ghc.html</id><title type="text">Haskellにおける記号の調べ方</title><updated>2021-12-25T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/2021/symbols-in-ghc.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;p&gt;この記事は&lt;a href=&#34;https://qiita.com/advent-calendar/2021/gseach&#34;&gt;ググって解決しづらかったこと &lt;span class=&#34;ascii&#34;&gt;Advent Calendar 2021&lt;/span&gt;&lt;/a&gt;の&lt;span class=&#34;ascii&#34;&gt;25&lt;/span&gt;日目の記事です。&lt;a href=&#34;https://wiki.haskell.jp/Hikers%20Guide%20to%20Haskell&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp Wiki&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;の歩き方&lt;/a&gt;というページにもほぼ同じことを書きましたが、今回はよい機会なので実例を加えつつ詳しく紹介させてください。&lt;/p&gt;
&lt;div id=&#34;table-of-contents-outer&#34;&gt;
&lt;div id=&#34;table-of-contents&#34;&gt;
&lt;div class=&#34;table-of-contents-title&#34;&gt;
Contents
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#二項演算子記号関数の調べ方&#34; title=&#34;二項演算子記号関数の調べ方&#34;&gt;二項演算子（記号関数）の調べ方&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#ユーザーが定義した二項演算子ではないものの調べ方&#34; title=&#34;ユーザーが定義した二項演算子ではないものの調べ方&#34;&gt;ユーザーが定義した二項演算子ではないものの調べ方&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#まとめ&#34; title=&#34;まとめ&#34;&gt;まとめ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id=&#34;二項演算子記号関数の調べ方&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#二項演算子記号関数の調べ方&#34; title=&#34;二項演算子記号関数の調べ方&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;二項演算子（記号関数）の調べ方&lt;/h1&gt;
&lt;p&gt;よく知られているとおり、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;には二項演算子をプログラマーがかなり自由に定義できるという、とても変わった特徴があります。他のプログラミング言語でも使う標準的なもの（例&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; &lt;code&gt;+&lt;/code&gt;&lt;span class=&#34;ascii&#34;&gt;,&lt;/span&gt; &lt;code&gt;*&lt;/code&gt;&lt;span class=&#34;ascii&#34;&gt;,&lt;/span&gt; &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;など）を名前空間を絞って置き換えるほか、&lt;a href=&#34;https://hackage.haskell.org/package/lens-5.1/docs/Control-Lens-Operators.html&#34;&gt;例えばかの&lt;span class=&#34;ascii&#34;&gt;lens&lt;/span&gt;パッケージのように&lt;/a&gt;、ライブラリーの作者があたかも新しい構文を作り上げるかのごとく独自の二項演算子を提供することができます。&lt;/p&gt;
&lt;p&gt;これは面白い機能ではあるものの、しばしば混乱を招く機能でもあります。後述するその他の記号との区別がつきにくいですし、一般的な検索エンジンで検索することさえままなりません。&lt;a href=&#34;https://blog.fkoji.com/2017/03052055.html&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Google&lt;/span&gt;はプログラミングでよく使われる記号による検索をサポートはしている&lt;/a&gt;ものの、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;でしか見ないような記号の組み合わせは到底無理でしょう。&lt;/p&gt;
&lt;p&gt;そんな背景もあり、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;を使う人はしばしば&lt;a href=&#34;https://hoogle.haskell.org/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Hoogle&lt;/span&gt;&lt;/a&gt;などの、関数名で検索できる検索エンジンを使用することになります。こちらは二項演算子の名前での検索もサポートしています。&lt;/p&gt;
&lt;p&gt;例えば&lt;span class=&#34;ascii&#34;&gt;lens&lt;/span&gt;パッケージでおなじみの&lt;code&gt;^.&lt;/code&gt;で検索すると&lt;a href=&#34;https://hoogle.haskell.org/?hoogle=%5E.&#34;&gt;次のような結果になりました&lt;/a&gt;&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&#34;/img/2021/symbols-in-ghc/hoogle.png&#34; alt=&#34;Hoogleによる検索結果の例&#34; /&gt;
&lt;figcaption aria-hidden=&#34;true&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Hoogle&lt;/span&gt;による検索結果の例&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;lens&lt;/span&gt;パッケージ以外でも、同様の&lt;code&gt;^.&lt;/code&gt;が定義されているのが分かりますね。&lt;span class=&#34;ascii&#34;&gt;lens&lt;/span&gt;パッケージは依存関係がとても大きい一方、&lt;code&gt;^.&lt;/code&gt;などの定義は十分単純でコピペしてもいいくらい小さいので、このようにいくつものパッケージで定義されています。&lt;/p&gt;
&lt;p&gt;また、特によく使われる二項演算子は&lt;span class=&#34;ascii&#34;&gt;FPComplete&lt;/span&gt;のウェブサイトでもまとめられています&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.fpcomplete.com/haskell/tutorial/operators/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Operator Glossary&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;ユーザーが定義した二項演算子ではないものの調べ方&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#ユーザーが定義した二項演算子ではないものの調べ方&#34; title=&#34;ユーザーが定義した二項演算子ではないものの調べ方&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;ユーザーが定義した二項演算子ではないものの調べ方&lt;/h1&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;、というかそのデファクトスタンダードな処理系である&lt;span class=&#34;ascii&#34;&gt;GHC&lt;/span&gt;では、&lt;a href=&#34;https://haskell.jp/blog/posts/2018/about-ghc-exts-1.html&#34;&gt;言語拡張&lt;/a&gt;という形で長年新しい構文が提案されています&lt;a href=&#34;#fn1&#34; class=&#34;footnote-ref&#34; id=&#34;fnref1&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;。その中には、当然これまでにない方法で記号を使っているものもあります。そうした記号はプログラマーが定義した関数ではないので、前述の&lt;span class=&#34;ascii&#34;&gt;Hoogle&lt;/span&gt;などを使った方法が通用しません。そこで、当ブログにも何度も寄稿いただいた&lt;span class=&#34;ascii&#34;&gt;@takenobu_hs&lt;/span&gt;さんが、言語拡張によるものも含めた、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;の構文における記号の一覧を作ってくださいました！&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/takenobu-hs/haskell-symbol-search-cheatsheet&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;takenobu-hs/haskell-symbol-search-cheatsheet&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;実は日本語版も&lt;a href=&#34;https://qiita.com/takenobu-hs/items/b95f0a4409c59440d4a9&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Qiita&lt;/span&gt;に&lt;/a&gt;あるのですが、上記の&lt;span class=&#34;ascii&#34;&gt;GitHub&lt;/span&gt;版の方が更新されているようです。そこで、今回はおまけとして、&lt;a href=&#34;https://github.com/takenobu-hs/haskell-symbol-search-cheatsheet#--overloadedrecorddot&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;GitHub&lt;/span&gt;版の方にも載っている&lt;/a&gt;、&lt;span class=&#34;ascii&#34;&gt;GHC&lt;/span&gt;に最近（バージョン&lt;span class=&#34;ascii&#34;&gt;9.2.1&lt;/span&gt;以降に）追加された、新しいピリオド &lt;code&gt;.&lt;/code&gt; の使い方を紹介しましょう。&lt;/p&gt;
&lt;p&gt;従来、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;でピリオドといえば関数合成を表す二項演算子でした&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; f x &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; x &lt;span class=&#34;op&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; g x &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; x &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; h &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; g &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; f&lt;/span&gt;
&lt;span id=&#34;cb1-4&#34;&gt;&lt;a href=&#34;#cb1-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; h &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-5&#34;&gt;&lt;a href=&#34;#cb1-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dv&#34;&gt;9&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;-- 2 に + 1 して * 3 した結果&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;数学における関数合成の記号「&lt;span class=&#34;ascii&#34;&gt;g&lt;/span&gt; ∘ &lt;span class=&#34;ascii&#34;&gt;f&lt;/span&gt;」に似せてピリオドを採用したのでしょう。しかし、世は今まさに&lt;strong&gt;大「ピリオドといえばフィールド&lt;a href=&#34;#fn2&#34; class=&#34;footnote-ref&#34; id=&#34;fnref2&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;へのアクセス演算子じゃろがい」時代&lt;/strong&gt;です。それでなくても&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;のレコード型は扱いにくいと言われているのに、フィールドへのアクセスまで変なやり方でした&lt;a href=&#34;#fn3&#34; class=&#34;footnote-ref&#34; id=&#34;fnref3&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;SomeRecord&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;SomeRecord&lt;/span&gt; {&lt;span class=&#34;ot&#34;&gt; field1 ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;,&lt;span class=&#34;ot&#34;&gt; field2 ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; }&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-4&#34;&gt;&lt;a href=&#34;#cb2-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;someRecord &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;SomeRecord&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;value1&amp;quot;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-5&#34;&gt;&lt;a href=&#34;#cb2-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-6&#34;&gt;&lt;a href=&#34;#cb2-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; field1 someRecord&lt;/span&gt;
&lt;span id=&#34;cb2-7&#34;&gt;&lt;a href=&#34;#cb2-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;value1&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-8&#34;&gt;&lt;a href=&#34;#cb2-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-9&#34;&gt;&lt;a href=&#34;#cb2-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; field2 someRecord&lt;/span&gt;
&lt;span id=&#34;cb2-10&#34;&gt;&lt;a href=&#34;#cb2-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;そこで、&lt;span class=&#34;ascii&#34;&gt;GHC 9.2&lt;/span&gt;からは&lt;a href=&#34;https://downloads.haskell.org/ghc/9.2.1/docs/html/users_guide/exts/overloaded_record_dot.html#overloaded-record-dot&#34;&gt;&lt;code&gt;OverloadedRecordDot&lt;/code&gt;&lt;/a&gt;という言語拡張が導入され、これを有効にしたファイルではおなじみの言語のようにピリオドでレコードのフィールドにアクセスできるようになりました&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;（以下は&lt;span class=&#34;ascii&#34;&gt;GHCi&lt;/span&gt;で使用した例です）&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;set &lt;span class=&#34;op&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;XOverloadedRecordDot&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-2&#34;&gt;&lt;a href=&#34;#cb3-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-3&#34;&gt;&lt;a href=&#34;#cb3-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; someRecord&lt;span class=&#34;op&#34;&gt;.&lt;/span&gt;field1&lt;/span&gt;
&lt;span id=&#34;cb3-4&#34;&gt;&lt;a href=&#34;#cb3-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;value1&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-5&#34;&gt;&lt;a href=&#34;#cb3-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-6&#34;&gt;&lt;a href=&#34;#cb3-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; someRecord&lt;span class=&#34;op&#34;&gt;.&lt;/span&gt;field2&lt;/span&gt;
&lt;span id=&#34;cb3-7&#34;&gt;&lt;a href=&#34;#cb3-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-8&#34;&gt;&lt;a href=&#34;#cb3-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-9&#34;&gt;&lt;a href=&#34;#cb3-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- ⚠️ピリオドの前後に空白を入れると関数合成として解釈されてしまう！&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-10&#34;&gt;&lt;a href=&#34;#cb3-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ghci&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; someRecord &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; field2&lt;/span&gt;
&lt;span id=&#34;cb3-11&#34;&gt;&lt;a href=&#34;#cb3-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-12&#34;&gt;&lt;a href=&#34;#cb3-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;lt;&lt;/span&gt;interactive&lt;span class=&#34;op&#34;&gt;&amp;gt;:&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-13&#34;&gt;&lt;a href=&#34;#cb3-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;op&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Couldn&amp;#39;t&lt;/span&gt; match expected &lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; ‘&lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; c’&lt;/span&gt;
&lt;span id=&#34;cb3-14&#34;&gt;&lt;a href=&#34;#cb3-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                  with actual &lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; ‘&lt;span class=&#34;dt&#34;&gt;SomeRecord&lt;/span&gt;’&lt;/span&gt;
&lt;span id=&#34;cb3-15&#34;&gt;&lt;a href=&#34;#cb3-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;op&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;In&lt;/span&gt; the first argument &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt; ‘(&lt;span class=&#34;op&#34;&gt;.&lt;/span&gt;)’, namely ‘someRecord’&lt;/span&gt;
&lt;span id=&#34;cb3-16&#34;&gt;&lt;a href=&#34;#cb3-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;dt&#34;&gt;In&lt;/span&gt; the expression&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; someRecord &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; field2&lt;/span&gt;
&lt;span id=&#34;cb3-17&#34;&gt;&lt;a href=&#34;#cb3-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;dt&#34;&gt;In&lt;/span&gt; an equation for ‘it’&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; it &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; someRecord &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; field2&lt;/span&gt;
&lt;span id=&#34;cb3-18&#34;&gt;&lt;a href=&#34;#cb3-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;op&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Relevant&lt;/span&gt; bindings include&lt;/span&gt;
&lt;span id=&#34;cb3-19&#34;&gt;&lt;a href=&#34;#cb3-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;        it ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;SomeRecord&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; c (bound at &lt;span class=&#34;op&#34;&gt;&amp;lt;&lt;/span&gt;interactive&lt;span class=&#34;op&#34;&gt;&amp;gt;:&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;OverloadedRecordDot&lt;/code&gt;についてのより詳しい解説は、&lt;a href=&#34;https://youtu.be/haZl-q6mfyk?t=2581&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Day 2021&lt;/span&gt;における、&lt;span class=&#34;ascii&#34;&gt;fumieval&lt;/span&gt;さんの発表&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h1 id=&#34;まとめ&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#まとめ&#34; title=&#34;まとめ&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;まとめ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;他のプログラマーが定義した、二項演算子（記号関数）を調べるときは&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://hoogle.haskell.org/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Hoogle&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;補足&lt;span class=&#34;ascii&#34;&gt;: Stackage&lt;/span&gt;の最新の&lt;span class=&#34;ascii&#34;&gt;LTS&lt;/span&gt;から検索したいときは&lt;a href=&#34;https://www.stackage.org/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Stackage&lt;/span&gt;&lt;/a&gt;のページ上部にあるフォームで検索してみましょう。こちらも内部は&lt;span class=&#34;ascii&#34;&gt;Hoogle&lt;/span&gt;が使われています。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;それ以外の場合は&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/takenobu-hs/haskell-symbol-search-cheatsheet&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;takenobu-hs/haskell-symbol-search-cheatsheet&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;のレコード型に嫌気が差したら&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/haZl-q6mfyk?t=2581&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Day 2021&lt;/span&gt;における、&lt;span class=&#34;ascii&#34;&gt;fumieval&lt;/span&gt;さんの発表&lt;/a&gt;を観て&lt;a href=&#34;https://downloads.haskell.org/ghc/9.2.1/docs/html/users_guide/exts/overloaded_record_dot.html#overloaded-record-dot&#34;&gt;&lt;code&gt;OverloadedRecordDot&lt;/code&gt;拡張&lt;/a&gt;について勉強しましょう。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;🎁それでは&lt;span class=&#34;ascii&#34;&gt;2022&lt;/span&gt;年も&lt;span class=&#34;ascii&#34;&gt;Happy Haskell Hacking!!&lt;/span&gt;🎅&lt;/p&gt;
&lt;section id=&#34;footnotes&#34; class=&#34;footnotes footnotes-end-of-document&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn1&#34;&gt;&lt;p&gt;余談&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; &lt;a href=&#34;https://github.com/ghc-proposals/ghc-proposals&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;ghc-proposals&lt;/span&gt;&lt;/a&gt;に送られた&lt;span class=&#34;ascii&#34;&gt;Pull request&lt;/span&gt;を見ると、今どのような提案が議論されているか分かります。&lt;a href=&#34;#fnref1&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn2&#34;&gt;&lt;p&gt;他のプログラミング言語では「プロパティー」と呼ばれることも多いですが、ここでは&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;のレコード型における用語に合わせました。&lt;a href=&#34;#fnref2&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn3&#34;&gt;&lt;p&gt;個人的にはゲッターが関数になるのはとても直感的な気がして割と好きでしたが、確かにデメリットもとても多い仕様でした。セッターは単純な関数になってないですしね。&lt;a href=&#34;#fnref3&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
                &lt;i class=&#34;glyphicon glyphicon-chevron-left&#34; aria-hidden=&#34;true&#34; style=&#34;margin-right: 5px;&#34;&gt;&lt;/i&gt;
                &lt;a href=&#34;/posts/2021/text-mono-traversable.html&#34; lang=&#34;ja&#34;&gt;文字列型を抽象化するのにはmono-traversableパッケージがいいかも&lt;/a&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/2021/haskell-day-2021.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;Haskell Day 2021を開催します&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&gt;

</summary></entry><entry><id>https://matsubara0507.github.io/posts/2021-12-20-fix-rules_haskell-for-ghc_9_2_1.html</id><title type="text">Bazel でも GHC 9.2.1 でビルドがしたい</title><updated>2021-12-20T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2021-12-20-fix-rules_haskell-for-ghc_9_2_1.html"/></entry><entry><id>https://matsubara0507.github.io/posts/2021-12-09-use-morpheus-graphql-for-github.html</id><title type="text">Haskell Morpheus GraphQL で GitHub API を試す</title><updated>2021-12-09T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2021-12-09-use-morpheus-graphql-for-github.html"/></entry><entry><id>https://fumieval.hatenablog.com/entry/2021/12/03/212534</id><title type="text">Oath: 安全、高速、合成可能な並行処理</title><updated>2021-12-03T21:25:34+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2021/12/03/212534"/><summary type="html">TL;DR github.com 並行処理を簡潔かつ安全に記述できるライブラリを作った。ApplicativeDo拡張を使って、以下のようにoathの引数として与えたIOアクションを同時に実行し、結果を集める処理を書ける。いずれかが例外を投げた場合、残りをキャンセルするためリソースを漏らす心配がない。 evalOath $ do a &lt;- oath $ ... b &lt;- oath $ ... f a b 経緯 Haskellは並行処理が得意とされている。事実、軽量スレッド、MVar、STMといった処理系によるサポートが充実しており、HackageのConcurrencyカテゴリには235ものパ…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2021-11-28-use-latest-ghc-with-slack.html</id><title type="text">Haskell Stack で Stackage に無い GHC を使う</title><updated>2021-11-28T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2021-11-28-use-latest-ghc-with-slack.html"/></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2021/09/30/213008</id><title type="text">VPC Reachability Analyzer と形式手法</title><updated>2021-09-30T21:30:08+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2021/09/30/213008"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された AWS Dev Day Online Japan 2021 で、AWS の VPC Reachability Analyzer とそのバックエンドである Tiros について発表してきました。公募 CFP 枠です。 www.youtube.com 講演概要 このプレゼンの大きな目標は、VPC Reachability Analyzer のバックエンドである検査エンジン Tiros の論文 [Bac19] を解説することです。そのための道筋として、Section 1 で VPC Reachability Analyzer の機能を簡単に紹介した後、S…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2021-09-30-rules_elm-elm_test.html</id><title type="text">rules_elm に elm-test するルールを追加する</title><updated>2021-09-30T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2021-09-30-rules_elm-elm_test.html"/></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2021/09/04/055934</id><title type="text">CI/CD Conference 2021 で Zelkova の論文について話してきました</title><updated>2021-09-04T05:59:34+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2021/09/04/055934"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された CI/CD Conference 2021 で、AWS の IAM Access Anazlyer のバックエンドとして使用されている検査エンジン Zelkova、およびその元となった論文について発表してきました。公募 CFP 枠です。 発表の大筋は、少し前に July Tech Festa 2021 で登壇した際のものと共通です。関連リンク集などは以下の記事にまとめてあるので、よかったらこちらも合わせてお読みください。 ccvanishing.hateblo.jp 内容面では、前回の発表時間 20 分に対して今回は 40 分の枠をもらっていたので…</summary></entry><entry><id>https://matsubara0507.github.io/posts/2021-08-19-haskell-use-generated-file-by-bazel.html</id><title type="text">Bazel で生成したファイルを Haskell から参照する</title><updated>2021-08-19T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2021-08-19-haskell-use-generated-file-by-bazel.html"/></entry><entry><id>https://matsubara0507.github.io/posts/2021-07-31-rules_elm-elm_dependencies.html</id><title type="text">rules_elm で依存パッケージのインストールをキャッシュする</title><updated>2021-07-31T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2021-07-31-rules_elm-elm_dependencies.html"/></entry><entry><id>https://matsubara0507.github.io/posts/2021-07-30-rules_haskell-with-setup_deps.html</id><title type="text">Bazel で Haskell の Custom Setup をする</title><updated>2021-07-30T00:00:00Z</updated><author><name>matsubara0507</name></author><link href="https://matsubara0507.github.io/posts/2021-07-30-rules_haskell-with-setup_deps.html"/></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2021/07/18/211619</id><title type="text">July Tech Festa 2021 で IAM Access Analyzer と Zelkova について話してきました</title><updated>2021-07-18T21:16:19+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2021/07/18/211619"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された July Tech Festa 2021 で、AWS のアクセス制御検査ツール Zelkova について発表してきました。公募 CFP 枠です。 techfesta.connpass.com 講演概要 www.youtube.com 一般に、AWS 上のリソース設定を変更したときに何が起こるのかを事前に検査するのは難しい作業です。特に、複数の設定がマージされた結果として最終的なアクセス許可が決まるような場合、単独の項目をルールベースでチェックするだけでは限界があります。 今回の発表中では、インフラに対する検査の水準を以下の 3 つのレベルに分けて定…</summary></entry><entry><id>https://haskell.jp/blog/posts/2021/haskell-day-2021.html</id><title type="text">Haskell Day 2021を開催します</title><updated>2021-06-14T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/2021/haskell-day-2021.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;p&gt;&lt;a href=&#34;https://haskell.jp/haskell-day-2021/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Day 2021&lt;/span&gt;&lt;/a&gt;を開催します！&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://haskell.jp/haskell-day-2021/&#34;&gt;&lt;img src=&#34;../../img/2021/haskell-day-2021/ogp.png&#34; alt=&#34;Haskell Day 2021&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;こんにちは&lt;span class=&#34;ascii&#34;&gt;kakkun61&lt;/span&gt;こと岡本和樹です。&lt;/p&gt;
&lt;p&gt;この記事では&lt;a href=&#34;https://haskell.jp/haskell-day-2021/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Day 2021&lt;/span&gt;&lt;/a&gt;の紹介と開催の経緯などを記載します。&lt;/p&gt;
&lt;div id=&#34;table-of-contents-outer&#34;&gt;
&lt;div id=&#34;table-of-contents&#34;&gt;
&lt;div class=&#34;table-of-contents-title&#34;&gt;
Contents
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#経緯&#34; title=&#34;経緯&#34;&gt;経緯&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#発表者募集&#34; title=&#34;発表者募集&#34;&gt;発表者募集&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#参加登録&#34; title=&#34;参加登録&#34;&gt;参加登録&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id=&#34;経緯&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#経緯&#34; title=&#34;経緯&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;経緯&lt;/h1&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Day&lt;/span&gt;は日本語で開催される&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;に関するイベントとしては最多の参加者を誇るイベントです。これまで&lt;span class=&#34;ascii&#34;&gt;2012&lt;/span&gt;・&lt;span class=&#34;ascii&#34;&gt;2016&lt;/span&gt;・&lt;span class=&#34;ascii&#34;&gt;2018&lt;/span&gt;・&lt;span class=&#34;ascii&#34;&gt;2019&lt;/span&gt;と開催してきました。新型コロナウイルスの影響により、残念ながら&lt;span class=&#34;ascii&#34;&gt;2020&lt;/span&gt;は開催しませんでしたが、&lt;span class=&#34;ascii&#34;&gt;2021&lt;/span&gt;は&lt;em&gt;オンライン&lt;/em&gt;イベントとして開催します。&lt;/p&gt;
&lt;p&gt;このようなオンラインイベントの開催は未経験だったため、さまざまなイベント形式を検討した結果、今回は事前録画動画の予約公開という形式を採用しました。生放送ももちろん検討しましたが、ノウハウ不足の中で一発勝負という生放送はリスクが大きいという判断をしました。録画公開における臨場感の不足をおぎなうことを期待し、&lt;span class=&#34;ascii&#34;&gt;YouTube&lt;/span&gt;の&lt;a href=&#34;https://creatoracademy.youtube.com/page/course/hype-with-premieres&#34;&gt;プレミア公開&lt;/a&gt;を使用しリアルタイムチャットによる発表者と視聴者・視聴者同士の交流をできるように予定しています。&lt;/p&gt;
&lt;h1 id=&#34;発表者募集&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#発表者募集&#34; title=&#34;発表者募集&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;発表者募集&lt;/h1&gt;
&lt;p&gt;現在&lt;a href=&#34;https://haskell.jp/haskell-day-2021/#call-for-papers&#34;&gt;発表者募集&lt;/a&gt;中です！&lt;/p&gt;
&lt;p&gt;今回はオンライン開催ということで、お手数ですが発表者にもオンサイトのイベントと異なった準備をお願いすることになります。運営としてできるかぎりのサポートをしますので安心して応募いただければと思います。&lt;/p&gt;
&lt;h1 id=&#34;参加登録&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#参加登録&#34; title=&#34;参加登録&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;参加登録&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://haskell-jp.connpass.com/event/215363/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Connpass&lt;/span&gt;&lt;/a&gt;にて参加登録の受け付けもしていますので視聴者の方も登録をお願いします。&lt;/p&gt;
&lt;p&gt;その他のくわしい情報は&lt;a href=&#34;https://haskell.jp/haskell-day-2021/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Day 2021&lt;/span&gt;イベントページ&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;p&gt;みなさまのご応募をお待ちしています。またお体にお気をつけください。&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
                &lt;i class=&#34;glyphicon glyphicon-chevron-left&#34; aria-hidden=&#34;true&#34; style=&#34;margin-right: 5px;&#34;&gt;&lt;/i&gt;
                &lt;a href=&#34;/posts/2021/symbols-in-ghc.html&#34; lang=&#34;ja&#34;&gt;Haskellにおける記号の調べ方&lt;/a&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/grc.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;「相互を尊重したコミュニケーションのためのガイドライン」制定のお知らせ&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&gt;

</summary></entry><entry><id>https://haskell.jp/blog/posts/grc.html</id><title type="text">「相互を尊重したコミュニケーションのためのガイドライン」制定のお知らせ</title><updated>2021-05-30T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/grc.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;hr /&gt;
&lt;p&gt;&lt;a href=&#34;about_admins.html&#34;&gt;先日の&lt;span class=&#34;ascii&#34;&gt;Haskell-jp Admins&lt;/span&gt;&lt;/a&gt;と同様に事務的な連絡で恐縮ですが、当ブログや&lt;a href=&#34;https://haskell.jp/signin-slack.html&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;Slack Workspace&lt;/span&gt;&lt;/a&gt;、&lt;a href=&#34;https://github.com/haskell-jp&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;GitHub&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;Organization&lt;/span&gt;&lt;/a&gt;などにおけるコミュニケーションに適用される、&lt;a href=&#34;https://github.com/haskell-jp/community/blob/master/GRC.md&#34;&gt;「相互を尊重したコミュニケーションのためのガイドライン」&lt;/a&gt;を制定致しました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/haskell-jp/community/blob/master/GRC.md&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt; 相互を尊重したコミュニケーションのためのガイドライン&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;こちらは&lt;a href=&#34;https://haskell.foundation/guidelines-for-respectful-communication/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Foundation&lt;/span&gt;における&lt;span class=&#34;ascii&#34;&gt;Guidelines for Respectful Communication (GRC)&lt;/span&gt;&lt;/a&gt;を日本語に翻訳し、運用主体などを&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;における実態に合わせて書き換えたものです。いわゆる「行動規範&lt;small&gt;（&lt;span class=&#34;ascii&#34;&gt;Code Of Conduct&lt;/span&gt;。しばしば「&lt;span class=&#34;ascii&#34;&gt;COC&lt;/span&gt;」と略されます）&lt;/small&gt;」と同じ役割を果たすものですが、行動規範と異なり、禁止事項よりも推奨事項を数多く挙げているのが特徴です。&lt;a href=&#34;https://github.com/haskell-jp/community/pull/29&#34;&gt;この&lt;span class=&#34;ascii&#34;&gt;GRC&lt;/span&gt;を翻訳する前に、&lt;span class=&#34;ascii&#34;&gt;COC&lt;/span&gt;を提案した際の議論&lt;/a&gt;において&lt;span class=&#34;ascii&#34;&gt;GRC&lt;/span&gt;のこうした特徴が好まれ、採用に至りました。&lt;/p&gt;
&lt;p&gt;この&lt;span class=&#34;ascii&#34;&gt;GRC&lt;/span&gt;は、今後&lt;a href=&#34;https://haskell.jp/signin-slack.html&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;Slack Workspace&lt;/span&gt;&lt;/a&gt;や&lt;a href=&#34;https://github.com/haskell-jp/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;GitHub&lt;/span&gt;における&lt;span class=&#34;ascii&#34;&gt;Organization&lt;/span&gt;が管理するリポジトリー&lt;/a&gt;、それから&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;として開催するイベントなど、様々な場面で適用されます。参加されるみなさんはご理解の上、快適なコミュニティー活動をお楽しみください。&lt;/p&gt;
&lt;p&gt;加えて、もちろん今秋開催予定の&lt;a href=&#34;https://haskell.jp/haskell-day-2021/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Day 2021&lt;/span&gt;&lt;/a&gt;においても、こちらの&lt;span class=&#34;ascii&#34;&gt;GRC&lt;/span&gt;を採用します。参加者、発表者、運営者の方々はご理解とご協力をよろしくお願いします。&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
                &lt;i class=&#34;glyphicon glyphicon-chevron-left&#34; aria-hidden=&#34;true&#34; style=&#34;margin-right: 5px;&#34;&gt;&lt;/i&gt;
                &lt;a href=&#34;/posts/2021/haskell-day-2021.html&#34; lang=&#34;ja&#34;&gt;Haskell Day 2021を開催します&lt;/a&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/about_admins.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;日本Haskellユーザーグループ管理委員会（Haskell-jp Admins）設立のお知らせ&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&gt;

</summary></entry><entry><id>https://kurokawh.blogspot.com/2018/05/emacscygwin-visual-studioemacs.html</id><title type="text">[emacs][cygwin] Visual Studioのemacs / emacsclient 連携設定</title><updated>2021-04-18T11:56:12.128+09:00</updated><author><name>Hiroyuki Kurokawa (hrkr)</name></author><link href="https://kurokawh.blogspot.com/2018/05/emacscygwin-visual-studioemacs.html"/><summary type="text">Visual Studioの外部ツール機能を利用して、Visual Studioで開いているファイルをショートカットキー一発で（orメニューから）emacs/emacsclientで開くことができる設定を紹介します。カーソル位置がemacsに引き継がれるのが地味に便利です。職場の都合などでビルド環境がVisual Studioだが、ビルド以外の作業は使い慣れたemacsを利用したい、という方にお勧めです。今の時代になぜWSLでなくcygwinなのか？という疑問をもたれる方がいると思いますが、このエントリはWSLがリリース前にメモを作って、ずっと公開しないまま眠っていたものです。せっかくの情報なので時代遅れを承知の上公開します。&amp;nbsp;

前提：
&#34;C:\cygwin64&#34;以下にcygwinをインストールし、cygwin上でemacs/emacsclientを利用している、自分の環境を</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2021/04/17/091533</id><title type="text">DevOpsDays Tokyo 2021 で Infrastructure as Code のテストについて話してきました</title><updated>2021-04-17T09:15:33+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2021/04/17/091533"/><summary type="html">こんにちは、チェシャ猫です。 先日開催された DevOpsDays Tokyo 2021 で Infrastructure as Code のテストについて発表してきました。公募 CFP 枠です。 今回の発表は、昨年の CloudOperatorDays Tokyo 2020 での講演をほぼそのまま再現しています。内容については前回登壇時に詳細な解説記事を書いたので、こちらもご参照ください。 ccvanishing.hateblo.jp オンサイト登壇 ここしばらく、どのカンファレンスもリモート開催がデフォルトになっていましたが、今回は久しぶりに会場まで行って登壇してきました。最後にオンサイト…</summary></entry><entry><id>https://haskell.jp/blog/posts/about_admins.html</id><title type="text">日本Haskellユーザーグループ管理委員会（Haskell-jp Admins）設立のお知らせ</title><updated>2021-03-29T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/about_admins.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;hr /&gt;
&lt;div id=&#34;table-of-contents-outer&#34;&gt;
&lt;div id=&#34;table-of-contents&#34;&gt;
&lt;div class=&#34;table-of-contents-title&#34;&gt;
Contents
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#重大な追記&#34; title=&#34;重大な追記&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;2022/09/18&lt;/span&gt; 重大な追記&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#背景&#34; title=&#34;背景&#34;&gt;背景&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#今後の活動と連絡先&#34; title=&#34;今後の活動と連絡先&#34;&gt;今後の活動と連絡先&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#現在の理事社員&#34; title=&#34;現在の理事社員&#34;&gt;現在の理事・社員&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#所在地&#34; title=&#34;所在地&#34;&gt;所在地&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#定款&#34; title=&#34;定款&#34;&gt;定款&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id=&#34;重大な追記&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#重大な追記&#34; title=&#34;重大な追記&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;2022/09/18&lt;/span&gt; 重大な追記&lt;/h1&gt;
&lt;p&gt;⚠️一般社団法人としての日本&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;ユーザーグループ管理委員会は、&lt;span class=&#34;ascii&#34;&gt;2022&lt;/span&gt;年&lt;span class=&#34;ascii&#34;&gt;4&lt;/span&gt;月&lt;span class=&#34;ascii&#34;&gt;16&lt;/span&gt;日を以て解散しました。今後は任意団体として活動を続けます。詳細は&lt;a href=&#34;./2022/disband_admins.html&#34;&gt;一般社団法人日本&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;ユーザーグループ管理委員会 解散のお知らせ&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;p&gt;以下では、記録のために設立当時の記事をほぼそのまま残しています。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;去る&lt;span class=&#34;ascii&#34;&gt;2021&lt;/span&gt;年&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;月&lt;span class=&#34;ascii&#34;&gt;9&lt;/span&gt;日、任意団体であり明確な会員資格を持たない、&lt;a href=&#34;https://haskell.jp/blog/posts/about_us.html&#34;&gt;日本&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;ユーザーグループ（&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;）&lt;/a&gt;における共有財産やコミュニケーションの場の管理・運営を担う法人として、一般社団法人日本&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;ユーザーグループ管理委員会（通称 &lt;span class=&#34;ascii&#34;&gt;Haskell-jp Admins&lt;/span&gt;。&lt;a href=&#34;https://www.houjin-bangou.nta.go.jp/henkorireki-johoto.html?selHouzinNo=5020005014971&#34;&gt;法人番号 &lt;span class=&#34;ascii&#34;&gt;5020005014971&lt;/span&gt;&lt;/a&gt;）を設立しました。法人格を持つことを活かして、&lt;span class=&#34;ascii&#34;&gt;Haskell-jp Admins&lt;/span&gt;は次の事業に取り組みます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;プログラミング言語&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;に関するイベントの企画・開催・運営
&lt;ul&gt;
&lt;li&gt;イベントの会場を借りたり、ノベルティーを作成したりする際の名義として使用する予定です&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;haskell.jp&lt;/span&gt; ドメインの維持・管理&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://haskell.jp/signin-slack.html&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;Slack Workspace&lt;/span&gt;&lt;/a&gt;を始めとする、交流や情報共有を行う場の提供・管理・運営&lt;/li&gt;
&lt;li&gt;そのほか、上記に関連して必要なこと&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;背景&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#背景&#34; title=&#34;背景&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;背景&lt;/h1&gt;
&lt;p&gt;そもそもの設立の動機は、山下さん（&lt;a href=&#34;https://twitter.com/nobsun&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;@nobsun&lt;/span&gt;&lt;/a&gt;）の好意によって個人名義で保有していた&lt;span class=&#34;ascii&#34;&gt;haskell.jp&lt;/span&gt; ドメインを共同で管理出来るようにするためでした。ドメインを団体として保有するには、法人格と、法人名義の銀行口座が必要なのです。これ以外にも、&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;として共有する価値のあるアカウントを管理する際の名義として、随時「日本&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;ユーザーグループ管理委員会」を使用します。&lt;/p&gt;
&lt;h1 id=&#34;今後の活動と連絡先&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#今後の活動と連絡先&#34; title=&#34;今後の活動と連絡先&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;今後の活動と連絡先&lt;/h1&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp Admins&lt;/span&gt;が出来たからといって、&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;のあり方が大きく変わることはありません。今後も&lt;span class=&#34;ascii&#34;&gt;Slack&lt;/span&gt;で質問したり議論したり&lt;a href=&#34;https://haskell.jp/blog/&#34;&gt;ブログ&lt;/a&gt;記事を書いたりしましょう！&lt;a href=&#34;https://haskell.jp/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;haskell.jp&lt;/span&gt;&lt;/a&gt;というドメインを活かし、「公式面して」自由に活動する方をいつでも待っています！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公の場で提案・相談したい場合は&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;前述の&lt;a href=&#34;https://haskell.jp/signin-slack.html&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;Slack Workspace&lt;/span&gt;&lt;/a&gt;の&lt;span class=&#34;ascii&#34;&gt;#random&lt;/span&gt;チャンネルなどで投稿いただくか、&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/haskell-jp/community/issues&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;haskell-jp/community&lt;/span&gt;に&lt;span class=&#34;ascii&#34;&gt;issue&lt;/span&gt;&lt;/a&gt;として登録したり、&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://twitter.com/haskell_jp&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;Twitter&lt;/span&gt;アカウント &lt;span class=&#34;ascii&#34;&gt;@haskell_jp&lt;/span&gt;&lt;/a&gt;にメンションをください。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;プライベートに提案・相談したい場合は&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;haskell-jp-admins@googlegroups.com&lt;/span&gt; にメールを送ってください&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我々&lt;span class=&#34;ascii&#34;&gt;Haskell-jp Admins&lt;/span&gt;は、そうした活動をバックアップするために種々の問題に取り組んでいきます。&lt;/p&gt;
&lt;h1 id=&#34;現在の理事社員&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#現在の理事社員&#34; title=&#34;現在の理事社員&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;現在の理事・社員&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;代表理事&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; 山本悠滋（&lt;a href=&#34;https://twitter.com/igrep&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;@igrep&lt;/span&gt;&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;社員&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;中嶋大嗣（&lt;a href=&#34;https://twitter.com/nakaji_dayo/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;@nakaji_dayo&lt;/span&gt;&lt;/a&gt;&lt;span class=&#34;ascii&#34;&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;山下伸夫（&lt;a href=&#34;https://twitter.com/nobsun&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;@nobsun&lt;/span&gt;&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;岡本和樹（&lt;a href=&#34;https://twitter.com/kakkun61&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;@kakkun61&lt;/span&gt;&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;木下郁章（&lt;a href=&#34;https://twitter.com/fumieval&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;@fumieval&lt;/span&gt;&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;廣瀬達也（&lt;a href=&#34;https://twitter.com/lotz84_&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;@lotz84_&lt;/span&gt;&lt;/a&gt;）&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;所在地&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#所在地&#34; title=&#34;所在地&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;所在地&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class=&#34;ascii&#34;&gt;2022/09/18&lt;/span&gt; 編集&lt;/strong&gt;&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; 法人格を廃止するとともに、契約したバーチャルオフィスの規約に従い、こちらに記載していた住所も削除しました。&lt;/p&gt;
&lt;h1 id=&#34;定款&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#定款&#34; title=&#34;定款&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;定款&lt;/h1&gt;
&lt;p&gt;こちらに一部個人情報を削除した上で掲載しています。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/haskell-jp/community/blob/master/admins/article.md&#34;&gt;一般社団法人 日本&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;ユーザーグループ管理委員会 定款&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
                &lt;i class=&#34;glyphicon glyphicon-chevron-left&#34; aria-hidden=&#34;true&#34; style=&#34;margin-right: 5px;&#34;&gt;&lt;/i&gt;
                &lt;a href=&#34;/posts/grc.html&#34; lang=&#34;ja&#34;&gt;「相互を尊重したコミュニケーションのためのガイドライン」制定のお知らせ&lt;/a&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/2020/break-monad-law-with-writer.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;Writer Monadで気軽にMonad則を破る&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&gt;

</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2021/01/24/185819</id><title type="text">July Tech Festa 2021 winter で CockroachDB と TLA+ について話してきました</title><updated>2021-01-24T18:58:19+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2021/01/24/185819"/><summary type="html">こんにちは、チェシャ猫です。 インフラ技術のカンファレンス July Tech Festa 2021 winter で、形式手法ツール TLA+ が CockroachDB の設計に使用された事例について発表してきました。公募 CFP 枠です。 www.youtube.com 今回の登壇は、昨年の CloudNative Days Tokyo 2020 と同じ題材を扱っています。ただ、前回より持ち時間が長くなった分、前回のスライドで説明不足だった部分を拡充してあります。特に、CockroachDB 以外の TLA+ 採用事例や、分散システムにおける Chaos Engineering の位置付…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2021/01/06/GHC_%E6%BC%94%E7%AE%97%E5%AD%90%E5%84%AA%E5%85%88%E9%A0%86%E4%BD%8D%E3%83%88%E3%83%AA%E3%83%93%E3%82%A2</id><title type="text">GHC 演算子優先順位トリビア</title><updated>2021-01-06T07:13:09+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2021/01/06/GHC_%E6%BC%94%E7%AE%97%E5%AD%90%E5%84%AA%E5%85%88%E9%A0%86%E4%BD%8D%E3%83%88%E3%83%AA%E3%83%93%E3%82%A2"/><summary type="html">GHC の演算子の優先順位には -1 がある（たぶん組込でしか使えない #Haskell pic.twitter.com/Xa0OIjvw5i— o̞͑kä̝mo̞͑to̞͑ kä̝zʊ̠kɪ̟ (@kakkun61) January 3, 2021</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2021/01/06/Case_Analysis_%E9%96%A2%E6%95%B0</id><title type="text">Case Analysis 関数</title><updated>2021-01-06T06:30:09+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2021/01/06/Case_Analysis_%E9%96%A2%E6%95%B0"/><summary type="html">今回は case analysis と呼ばれる関数の話です1。 data D a b c = C0 a b | C1 c 例えば上記のようなデータ型があった場合 case analysis 関数は次のようになります。 d :: (a -&gt; b -&gt; d) -&gt; (c -&gt; d) -&gt; D a b c -&gt; d d f _ (C0 a b) = f a b d _ f (C1 c) = f c 値構築子の数だけ関数を引数とし、対象のデータを最後の引数とします。それぞれの関数の型は値構築子の型に似ます。 C0 :: a -&gt; b -&gt; D a b c C1 :: c -&gt; D a b c d ::…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2021/01/01/%E7%B6%9A%E3%83%BB%E5%88%B9%E9%82%A3%E7%9A%84%E7%B4%94%E7%B2%8B%E9%96%A2%E6%95%B0%E7%9A%84%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E7%B7%9A%E5%BD%A2%E5%9E%8B</id><title type="text">続・刹那的純粋関数的データ構造と線形型</title><updated>2021-01-01T01:44:29+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2021/01/01/%E7%B6%9A%E3%83%BB%E5%88%B9%E9%82%A3%E7%9A%84%E7%B4%94%E7%B2%8B%E9%96%A2%E6%95%B0%E7%9A%84%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E7%B7%9A%E5%BD%A2%E5%9E%8B"/><summary type="html">The English version is at Dev. 前回の記事の追加情報です。 kakkun61.hatenablog.com pure 抜け道はなかった まあ、こういうインターフェースでありがちな pure で外に出す抜け道が存在するのですが。 最後にこういうことを無思慮に書いたわけですが、Dev に書いた英語版を Reddit に載せたところ有益な情報を教えてもらえました。 www.reddit.com I think the solution to the problem with empty might be to use the Ur (for &#34;unrestricted&#34;…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2020/12/29/190347</id><title type="text">新しいGHC拡張、NoFieldSelectorsについて</title><updated>2020-12-29T19:03:47+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2020/12/29/190347"/><summary type="html">今まで不満の多かったHaskellのレコードの扱いを改善するための一歩として、NoFieldSelectorsというGHC拡張の実装を進めている。 動機 Haskellにはレコードを定義するための構文がある。 data User = User { userId :: Int , userName :: Text } こう定義すると、各フィールドごとにuserId :: User -&gt; IntとuserName :: User -&gt; Textというゲッターに相当する関数が生成される。これらの関数は特別な意味合いを持っており、以下のレコード操作の構文にも利用できる。 構築 User { userI…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/12/25/%E5%88%B9%E9%82%A3%E7%9A%84%E7%B4%94%E7%B2%8B%E9%96%A2%E6%95%B0%E7%9A%84%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E7%B7%9A%E5%BD%A2%E5%9E%8B</id><title type="text">刹那的純粋関数的データ構造と線形型</title><updated>2020-12-25T09:37:13+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/12/25/%E5%88%B9%E9%82%A3%E7%9A%84%E7%B4%94%E7%B2%8B%E9%96%A2%E6%95%B0%E7%9A%84%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E7%B7%9A%E5%BD%A2%E5%9E%8B"/><summary type="html">The English version is at Dev. 『純粋関数型データ構造』（以降 PFDS）の5.2章に刹那的純粋関数的キューというものが出てきます。 https://asciidwango.jp/post/160831986220/%E7%B4%94%E7%B2%8B%E9%96%A2%E6%95%B0%E5%9E%8B%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0asciidwango.jp このキューは計算量の関係から1つの値に対して1回しか操作をしてはいけません。例えば下記操作列なら大丈夫ですが、その次の操作列では計算量が大きくな…</summary></entry><entry><id>https://haskell.jp/blog/posts/2020/break-monad-law-with-writer.html</id><title type="text">Writer Monadで気軽にMonad則を破る</title><updated>2020-12-25T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/2020/break-monad-law-with-writer.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;hr /&gt;
&lt;p&gt;🎅この記事は、&lt;a href=&#34;https://qiita.com/advent-calendar/2020/haskell&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Advent Calendar 2020&lt;/span&gt;&lt;/a&gt; &lt;span class=&#34;ascii&#34;&gt;25&lt;/span&gt;日目の記事です。&lt;br /&gt;
🎄&lt;span class=&#34;ascii&#34;&gt;Happy Christmas!!&lt;/span&gt;🎄&lt;/p&gt;
&lt;p&gt;今回は先日&lt;small&gt;（といっても元の質問の投稿からもう何ヶ月も経ってしまいましたが…）&lt;/small&gt;&lt;span class=&#34;ascii&#34;&gt;StackOverflow&lt;/span&gt;に上がったこちら👇の質問に対する回答の、続きっぽい話を書こうと思います。長いし、質問の回答からスコープが大きく外れてしまうので記事にしました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://ja.stackoverflow.com/questions/70079/%E3%83%A2%E3%83%8A%E3%83%89%E5%89%87%E3%82%92%E5%B4%A9%E3%81%97%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86%E4%BE%8B%E3%81%8C%E7%9F%A5%E3%82%8A%E3%81%9F%E3%81%84&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;haskell -&lt;/span&gt; モナド則を崩してしまう例が知りたい &lt;span class=&#34;ascii&#34;&gt;-&lt;/span&gt; スタック・オーバーフロー&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Monad&lt;/code&gt;と&lt;code&gt;Monoid&lt;/code&gt;にある重要な繋がりを説明した後、それを応用した&lt;code&gt;Writer&lt;/code&gt; &lt;code&gt;Monad&lt;/code&gt;がどう&lt;code&gt;Monoid&lt;/code&gt;を使って&lt;code&gt;Monad&lt;/code&gt;則を満たしているのか証明します。そして、&lt;code&gt;Writer&lt;/code&gt;のそうした性質を用いて簡単に&lt;code&gt;Monad&lt;/code&gt;則を破る例を紹介することで、読者のみなさんが&lt;code&gt;Monad&lt;/code&gt;則のみならず&lt;code&gt;do&lt;/code&gt;記法や&lt;code&gt;Monad&lt;/code&gt;そのものの性質について、よりはっきりとした理解が得られることを目指します。&lt;/p&gt;
&lt;div id=&#34;table-of-contents-outer&#34;&gt;
&lt;div id=&#34;table-of-contents&#34;&gt;
&lt;div class=&#34;table-of-contents-title&#34;&gt;
Contents
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#サンプルコードについて&#34; title=&#34;サンプルコードについて&#34;&gt;サンプルコードについて&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#monadとmonoidの切っても切り離せない関係&#34; title=&#34;monadとmonoidの切っても切り離せない関係&#34;&gt;&lt;code&gt;Monad&lt;/code&gt;と&lt;code&gt;Monoid&lt;/code&gt;の切っても切り離せない関係&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#monoidの例&#34; title=&#34;monoidの例&#34;&gt;&lt;code&gt;Monoid&lt;/code&gt;の例&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#monoidとwriterの切っても切り離せない関係&#34; title=&#34;monoidとwriterの切っても切り離せない関係&#34;&gt;&lt;code&gt;Monoid&lt;/code&gt;と&lt;code&gt;Writer&lt;/code&gt;の切っても切り離せない関係&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#doと&#34; title=&#34;doと&#34;&gt;&lt;code&gt;do&lt;/code&gt;と&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#writer-monadの結合則とmonoidの結合則&#34; title=&#34;writer-monadの結合則とmonoidの結合則&#34;&gt;&lt;code&gt;Writer&lt;/code&gt; &lt;code&gt;Monad&lt;/code&gt;の結合則と&lt;code&gt;Monoid&lt;/code&gt;の結合則&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#関係を壊してみる&#34; title=&#34;関係を壊してみる&#34;&gt;関係を壊してみる&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#とmonoidの結合則&#34; title=&#34;とmonoidの結合則&#34;&gt;&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;と&lt;code&gt;Monoid&lt;/code&gt;の結合則&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#とmonadの結合則&#34; title=&#34;とmonadの結合則&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;と&lt;code&gt;Monad&lt;/code&gt;の結合則&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#do記法とmonadの結合則&#34; title=&#34;do記法とmonadの結合則&#34;&gt;&lt;code&gt;do&lt;/code&gt;記法と&lt;code&gt;Monad&lt;/code&gt;の結合則&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#まとめ&#34; title=&#34;まとめ&#34;&gt;まとめ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id=&#34;サンプルコードについて&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#サンプルコードについて&#34; title=&#34;サンプルコードについて&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;サンプルコードについて&lt;/h1&gt;
&lt;p&gt;本記事のサンプルコードは、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;の構文に準拠していないものを除いて、すべて&lt;a href=&#34;https://github.com/igrep/readme-test&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;readme-test&lt;/span&gt;&lt;/a&gt;というツールの&lt;a href=&#34;https://github.com/igrep/readme-test/tree/f6ce7a6f5ce5f5f8031cd5dfedc8c6e47c13b1f3&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;2020&lt;/span&gt;年&lt;span class=&#34;ascii&#34;&gt;12&lt;/span&gt;月&lt;span class=&#34;ascii&#34;&gt;13&lt;/span&gt;日時点の開発版&lt;/a&gt;でテストしました。こちらのツールはまだ開発中で、今後も仕様が大きく変わる可能性がありますが、この記事のサンプルコードをテストするのに必要な機能は十分にそろっています。この&lt;span class=&#34;ascii&#34;&gt;readme-test&lt;/span&gt;自体についてはいつか改めて共有します。&lt;/p&gt;
&lt;p&gt;また、テストの際に用いた環境は以下の通りです&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;Windows 10 Pro 20H2&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;GHC 8.10.1&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.stackage.org/nightly-2020-08-15&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Stackage nightly-2020-08-15&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;monadとmonoidの切っても切り離せない関係&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#monadとmonoidの切っても切り離せない関係&#34; title=&#34;monadとmonoidの切っても切り離せない関係&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;code&gt;Monad&lt;/code&gt;と&lt;code&gt;Monoid&lt;/code&gt;の切っても切り離せない関係&lt;/h1&gt;
&lt;p&gt;「&lt;a href=&#34;http://www.aoky.net/articles/james_iry/brief-incomplete-and-mostly-wrong.htm&#34;&gt;モナドは単なる自己関手の圏におけるモノイド対象だよ。何か問題でも？&lt;/a&gt;」というフレーズ（原文「&lt;a href=&#34;http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;A monad is a monoid in the category of endofunctors, what&lt;/span&gt;’&lt;span class=&#34;ascii&#34;&gt;s the problem?&lt;/span&gt;&lt;/a&gt;」が示すとおり、モナドとモノイド、&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;の識別子で言うところの&lt;code&gt;Monad&lt;/code&gt;と&lt;code&gt;Monoid&lt;/code&gt;には密接な関係があります。ぶっちゃけ、このフレーズの正確な意味を私は理解していないのですが、少なくとも&lt;code&gt;Monad&lt;/code&gt;と&lt;code&gt;Monoid&lt;/code&gt;には重要な共通点があることは知っています。それは、どちらも&lt;strong&gt;単位元と結合則&lt;/strong&gt;がある、ということです！&lt;/p&gt;
&lt;p&gt;具体的に&lt;code&gt;Monad&lt;/code&gt;と&lt;code&gt;Monoid&lt;/code&gt;の単位元・結合則を見てみましょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;!-- ReadmeTest: Ignore --&gt;
&lt;p&gt;&lt;code&gt;Monoid&lt;/code&gt;の単位元&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; 単位元である&lt;code&gt;mempty&lt;/code&gt;は、どんな値&lt;code&gt;x&lt;/code&gt;に&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;で足しても結果が変わらない！&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;x &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;mempty&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;mempty&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; x &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Monad&lt;/code&gt;の単位元&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; &lt;code&gt;return&lt;/code&gt;は&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の前に使っても後ろに使っても、&lt;code&gt;m&lt;/code&gt;や&lt;code&gt;k a&lt;/code&gt;の結果を変えない！&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; a &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k a) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;m &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; a) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Monoid&lt;/code&gt;の結合則&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; &lt;code&gt;x &amp;lt;&amp;gt; y &amp;lt;&amp;gt; z&lt;/code&gt;の結果は、&lt;code&gt;y &amp;lt;&amp;gt; z&lt;/code&gt;を先に計算しようと&lt;code&gt;x &amp;lt;&amp;gt; y&lt;/code&gt;を先に計算しようと変わらない！&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;x &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; (y &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; z) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (x &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; y) &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; z&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Monad&lt;/code&gt;の結合則&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; &lt;code&gt;m &amp;gt;&amp;gt;= \x -&amp;gt; k x &amp;gt;&amp;gt;= h&lt;/code&gt; の結果は、&lt;code&gt;\x -&amp;gt; k x &amp;gt;&amp;gt;= h&lt;/code&gt;を先に計算しようと、&lt;code&gt;m &amp;gt;&amp;gt;= (\x -&amp;gt; k x)&lt;/code&gt;を先に計算しようと変わらない！&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;m &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (m &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x)) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;※&lt;code&gt;Monad&lt;/code&gt;の単位元・結合則の式についてはわかりやすさのために&lt;a href=&#34;http://hackage.haskell.org/package/base-4.14.0.0/docs/Control-Monad.html#t:Monad&#34;&gt;引用元&lt;/a&gt;から少し形を変えています。&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;における&lt;code&gt;Monad&lt;/code&gt;・&lt;code&gt;Monoid&lt;/code&gt;とは、値がそれぞれの単位元・結合則をを満たす型です&lt;a href=&#34;#fn1&#34; class=&#34;footnote-ref&#34; id=&#34;fnref1&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;。それ以上でも、それ以下でもありません。&lt;/p&gt;
&lt;p&gt;それぞれの単位元・結合則を表す式は、一見して異なるものに見えるかも知れませんが、表す性質自体はよく似ています。なので、式を読んでもよく分からないという方は、上記に書いた日本語の説明をざっと眺めて覚えておいてください。特に、結合則における&lt;strong&gt;「～を先に計算しようと、～を先に計算しようと変わらない！」&lt;/strong&gt;の部分がこの後とても重要になります。&lt;/p&gt;
&lt;div id=&#34;monoid-examples&#34;&gt;

&lt;/div&gt;
&lt;h2 id=&#34;monoidの例&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#monoidの例&#34; title=&#34;monoidの例&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;code&gt;Monoid&lt;/code&gt;の例&lt;/h2&gt;
&lt;p&gt;ここまで読んで、&lt;code&gt;Monad&lt;/code&gt;はなんか聞いたことがあるけど&lt;code&gt;Monoid&lt;/code&gt;は初めて聞くよ、という方向けに補足すると、&lt;code&gt;Monoid&lt;/code&gt;とは例えば次のような型の値（と、それに対する処理）です。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Sum&lt;/code&gt;型&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; 数値&lt;small&gt;（&lt;span class=&#34;ascii&#34;&gt;Num&lt;/span&gt;型クラスのインスタンス）&lt;/small&gt;に対する、足し算を表す&lt;code&gt;Monoid&lt;/code&gt;のインスタンス&lt;/p&gt;
&lt;!-- ReadmeTest: AppendAsIs --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- これから紹介する処理に必要なモジュールのimport&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Monoid&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;!-- ReadmeTest: CompareAfterPrompt ByExpression --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- Sum aに対する &amp;lt;&amp;gt; は + と同等なので、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-2&#34;&gt;&lt;a href=&#34;#cb6-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getSum (&lt;span class=&#34;dt&#34;&gt;Sum&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Sum&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;mempty&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb6-3&#34;&gt;&lt;a href=&#34;#cb6-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- は、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-4&#34;&gt;&lt;a href=&#34;#cb6-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-5&#34;&gt;&lt;a href=&#34;#cb6-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- と同じ。&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;mempty&lt;/code&gt;が各&lt;code&gt;Monoid&lt;/code&gt;のインスタンスにおける単位元を返す、という点に注意してください。上記のとおり足し算の場合は&lt;code&gt;0&lt;/code&gt;です。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Product&lt;/code&gt;型&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; 数値&lt;small&gt;（&lt;span class=&#34;ascii&#34;&gt;Num&lt;/span&gt;型クラスのインスタンス）&lt;/small&gt;に対する、かけ算を表す&lt;code&gt;Monoid&lt;/code&gt;のインスタンス&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb7&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb7-1&#34;&gt;&lt;a href=&#34;#cb7-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- Product aに対する &amp;lt;&amp;gt; は * と同等なので、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-2&#34;&gt;&lt;a href=&#34;#cb7-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getProduct (&lt;span class=&#34;dt&#34;&gt;Product&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Product&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;mempty&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb7-3&#34;&gt;&lt;a href=&#34;#cb7-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- は、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-4&#34;&gt;&lt;a href=&#34;#cb7-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-5&#34;&gt;&lt;a href=&#34;#cb7-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- と同じ。&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;リスト型&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; リスト型の値に対する、結合 &lt;code&gt;(++)&lt;/code&gt;を表す&lt;code&gt;Monoid&lt;/code&gt;のインスタンス&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb8&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb8-1&#34;&gt;&lt;a href=&#34;#cb8-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- [a] に対する &amp;lt;&amp;gt; は ++ と同等なので、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-2&#34;&gt;&lt;a href=&#34;#cb8-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; [&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;] &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; [&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;] &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;mempty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-3&#34;&gt;&lt;a href=&#34;#cb8-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- は、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-4&#34;&gt;&lt;a href=&#34;#cb8-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;[&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;] &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; [&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;] &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; []&lt;/span&gt;
&lt;span id=&#34;cb8-5&#34;&gt;&lt;a href=&#34;#cb8-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- と同じ&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;All&lt;/code&gt;型&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; &lt;code&gt;Bool&lt;/code&gt;型の値に対する論理積&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;を表す&lt;code&gt;Monoid&lt;/code&gt;のインスタンス&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb9&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb9-1&#34;&gt;&lt;a href=&#34;#cb9-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getAll (&lt;span class=&#34;dt&#34;&gt;All&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;All&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb9-2&#34;&gt;&lt;a href=&#34;#cb9-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- は、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-3&#34;&gt;&lt;a href=&#34;#cb9-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb9-4&#34;&gt;&lt;a href=&#34;#cb9-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- と同じ&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;!-- ReadmeTest: ValidateAsExpression --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb10&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb10-1&#34;&gt;&lt;a href=&#34;#cb10-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- これが何を返すかは、想像してみてください！&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-2&#34;&gt;&lt;a href=&#34;#cb10-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;getAll &lt;span class=&#34;fu&#34;&gt;mempty&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Any&lt;/code&gt;型&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt; &lt;code&gt;Bool&lt;/code&gt;型の値に対する論理和&lt;code&gt;||&lt;/code&gt;を表す&lt;code&gt;Monoid&lt;/code&gt;のインスタンス&lt;/p&gt;
&lt;!-- ReadmeTest: CompareAfterPrompt ByExpression --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb11&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb11-1&#34;&gt;&lt;a href=&#34;#cb11-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getAny (&lt;span class=&#34;dt&#34;&gt;Any&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Any&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb11-2&#34;&gt;&lt;a href=&#34;#cb11-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- は、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb11-3&#34;&gt;&lt;a href=&#34;#cb11-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb11-4&#34;&gt;&lt;a href=&#34;#cb11-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- と同じ&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;!-- ReadmeTest: ValidateAsExpression --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb12&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb12-1&#34;&gt;&lt;a href=&#34;#cb12-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- これも何を返すかは、想像してみてください！&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-2&#34;&gt;&lt;a href=&#34;#cb12-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;getAny &lt;span class=&#34;fu&#34;&gt;mempty&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このように、&lt;code&gt;Monoid&lt;/code&gt;は他のプログラミング言語でもおなじみの、多くの二項演算を表しています。これらのインスタンスはすべて、先ほど紹介した「単位元」や「結合則」のルールを守っているので、気になった方はぜひチェックしてみてください&lt;a href=&#34;#fn2&#34; class=&#34;footnote-ref&#34; id=&#34;fnref2&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&#34;monoidとwriterの切っても切り離せない関係&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#monoidとwriterの切っても切り離せない関係&#34; title=&#34;monoidとwriterの切っても切り離せない関係&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;code&gt;Monoid&lt;/code&gt;と&lt;code&gt;Writer&lt;/code&gt;の切っても切り離せない関係&lt;/h1&gt;
&lt;p&gt;実はそんな&lt;code&gt;Monad&lt;/code&gt;と&lt;code&gt;Monoid&lt;/code&gt;の固い絆を象徴するような&lt;code&gt;Monad&lt;/code&gt;が、この世にはあります。そう、&lt;code&gt;Writer&lt;/code&gt;です！&lt;code&gt;Writer&lt;/code&gt;は&lt;code&gt;Monoid&lt;/code&gt;の単位元・結合則をそのまま活かすことによって&lt;code&gt;Monad&lt;/code&gt;の単位元・結合則を満たした&lt;code&gt;Monad&lt;/code&gt;であり、&lt;code&gt;Writer&lt;/code&gt;がどうやって&lt;code&gt;Monad&lt;/code&gt;則を満たしているのか知れば、&lt;code&gt;Monad&lt;/code&gt;則がどうやって成立するものなのかが、すっきりクリアになることでしょう。&lt;/p&gt;
&lt;p&gt;手始めに&lt;code&gt;Writer&lt;/code&gt;の定義と、&lt;code&gt;Writer&lt;/code&gt;が&lt;code&gt;Monad&lt;/code&gt;の各メソッドをどのように実装しているか見てみましょう。&lt;a href=&#34;https://www.sampou.org/haskell/a-a-monads/html/writermonad.html&#34;&gt;「モナドのすべて」における&lt;code&gt;Writer&lt;/code&gt;の紹介ページ&lt;/a&gt;から、少しリファクタリングしつつ引用します&lt;a href=&#34;#fn3&#34; class=&#34;footnote-ref&#34; id=&#34;fnref3&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;。&lt;/p&gt;
&lt;!-- ReadmeTest: AppendAsIs --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb13&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb13-1&#34;&gt;&lt;a href=&#34;#cb13-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- Writer型の定義&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb13-2&#34;&gt;&lt;a href=&#34;#cb13-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; w a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; {&lt;span class=&#34;ot&#34;&gt; runWriter ::&lt;/span&gt; (a, w) }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;タプルに対して&lt;code&gt;newtype&lt;/code&gt;していることから分かるとおり、&lt;code&gt;Writer&lt;/code&gt;の実態はただのタプルです。ただのタプルがどうやって&lt;code&gt;Monad&lt;/code&gt;になるのでしょう？その答えがこちら👇&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;!--
```haskell
instance Functor (Writer w) where
  fmap f (Writer (x, w)) = Writer (f x, w)

instance Monoid w =&gt; Applicative (Writer w) where
  pure a = Writer (a, mempty)
  Writer (f, w1) &lt;*&gt; Writer (x, w2) = Writer (f x, w1 &lt;&gt; w2)
```
--&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb14&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb14-1&#34;&gt;&lt;a href=&#34;#cb14-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- WriterのMonad型クラスの実装&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb14-2&#34;&gt;&lt;a href=&#34;#cb14-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- 実際のところFunctor, Applicativeのインスタンス定義も必要だけどここでは省略&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb14-3&#34;&gt;&lt;a href=&#34;#cb14-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Monoid&lt;/span&gt; w &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Monad&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; w) &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb14-4&#34;&gt;&lt;a href=&#34;#cb14-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, &lt;span class=&#34;fu&#34;&gt;mempty&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb14-5&#34;&gt;&lt;a href=&#34;#cb14-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; f &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb14-6&#34;&gt;&lt;a href=&#34;#cb14-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&#34;cb14-7&#34;&gt;&lt;a href=&#34;#cb14-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;     &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;return&lt;/code&gt;の定義は比較的シンプルですね。&lt;code&gt;mempty&lt;/code&gt;を受け取った値&lt;code&gt;a&lt;/code&gt;と一緒にタプルに入れて返すだけです。&lt;code&gt;Monad&lt;/code&gt;の単位元である&lt;code&gt;return&lt;/code&gt;では、&lt;code&gt;Monoid&lt;/code&gt;の単位元である&lt;code&gt;mempty&lt;/code&gt;を使うのです。&lt;/p&gt;
&lt;p&gt;一方、&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;はどう読めばいいでしょう？&lt;code&gt;let ... in ...&lt;/code&gt;の結果にあたる&lt;code&gt;Writer (b, w1 &amp;lt;&amp;gt; w2)&lt;/code&gt;に注目してください。&lt;/p&gt;
&lt;p&gt;まず、&lt;code&gt;b&lt;/code&gt;は&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の右辺である&lt;code&gt;f&lt;/code&gt;が返した結果です。&lt;code&gt;Writer&lt;/code&gt;の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;が返す、&lt;code&gt;Writer&lt;/code&gt;がラップしたタプルの一つ目の要素は、ここで&lt;code&gt;f&lt;/code&gt;が返した値の型と一致していなければなりません。&lt;code&gt;Writer&lt;/code&gt;において&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の型は&lt;code&gt;Writer w a -&amp;gt; (a -&amp;gt; Writer w b) -&amp;gt; Writer w b&lt;/code&gt;であり、右辺にあたる&lt;code&gt;f&lt;/code&gt;は&lt;code&gt;(a -&amp;gt; Writer w b)&lt;/code&gt;という型なので、&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;全体の戻り値&lt;code&gt;Writer w b&lt;/code&gt;と&lt;code&gt;f&lt;/code&gt;の戻り値が一致している必要があることがわかりますよね？&lt;/p&gt;
&lt;p&gt;さらに重要なのが&lt;code&gt;w1 &amp;lt;&amp;gt; w2&lt;/code&gt;です。ここであの&lt;code&gt;Monoid&lt;/code&gt;の演算子&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;が出てきました！&lt;code&gt;Writer&lt;/code&gt;は&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の中で&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;を使う&lt;code&gt;Monad&lt;/code&gt;なんですね！一体何と何を&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;しているのでしょう？まず、&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;の左辺である&lt;code&gt;w1&lt;/code&gt;は、左辺にあたる&lt;code&gt;Writer&lt;/code&gt;がタプルに保持していた&lt;code&gt;Monoid&lt;/code&gt;型クラスのインスタンスの値です。そして右辺の&lt;code&gt;w2&lt;/code&gt;は、&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の右辺に渡した関数&lt;code&gt;f&lt;/code&gt;が&lt;code&gt;b&lt;/code&gt;と一緒に返した&lt;code&gt;w2&lt;/code&gt;です。&lt;/p&gt;
&lt;p&gt;以上のことをまとめると、&lt;code&gt;Writer&lt;/code&gt;の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;は、&lt;/p&gt;
&lt;ol type=&#34;1&#34;&gt;
&lt;li&gt;左辺の&lt;code&gt;(a, w1)&lt;/code&gt;における&lt;code&gt;a&lt;/code&gt;を&lt;code&gt;f&lt;/code&gt;に渡して、&lt;/li&gt;
&lt;li&gt;&lt;code&gt;f&lt;/code&gt;が返した&lt;code&gt;(b, w2)&lt;/code&gt;における&lt;code&gt;b&lt;/code&gt;を、&lt;/li&gt;
&lt;li&gt;&lt;code&gt;w1&lt;/code&gt;と&lt;code&gt;w2&lt;/code&gt;と一緒に&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;でくっつけつつ返す、&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;という処理を行っています。&lt;code&gt;Writer&lt;/code&gt;は、「&lt;code&gt;b&lt;/code&gt;を返すついでに&lt;code&gt;w1&lt;/code&gt;と&lt;code&gt;w2&lt;/code&gt;を&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;でくっつける」と覚えてください。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Writer&lt;/code&gt;は、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Monad&lt;/code&gt;の単位元&lt;code&gt;return&lt;/code&gt;で&lt;code&gt;Monoid&lt;/code&gt;の単位元&lt;code&gt;mempty&lt;/code&gt;を使って、&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Monad&lt;/code&gt;の結合則を満たす&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;で、これまた&lt;code&gt;Monoid&lt;/code&gt;の結合則を満たす&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;を使っているのです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;やっぱり&lt;code&gt;Writer&lt;/code&gt;は&lt;code&gt;Monoid&lt;/code&gt;あっての&lt;code&gt;Monad&lt;/code&gt;と言えますね。&lt;/p&gt;
&lt;h2 id=&#34;doと&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#doと&#34; title=&#34;doと&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;code&gt;do&lt;/code&gt;と&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;さて、この「&lt;code&gt;b&lt;/code&gt;を返すついでに&lt;code&gt;w1&lt;/code&gt;と&lt;code&gt;w2&lt;/code&gt;を&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;でくっつける」という&lt;code&gt;Writer&lt;/code&gt;の振る舞いが象徴するように、大抵の&lt;code&gt;Monad&lt;/code&gt;のインスタンスにおける&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;は、&lt;strong&gt;何かしら値を返すついでに、何らかの処理を行う&lt;/strong&gt;よう実装されています。この「ついでに行われる処理」は&lt;code&gt;Monad&lt;/code&gt;のインスタンスを&lt;code&gt;do&lt;/code&gt;記法の中で扱うと、ますます静かに身を隠すようになります。&lt;/p&gt;
&lt;p&gt;こちらも&lt;code&gt;Writer&lt;/code&gt;を例に説明しましょう。まず、例示用に&lt;code&gt;Writer&lt;/code&gt;を作るアクションを適当に定義します。&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb15&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb15-1&#34;&gt;&lt;a href=&#34;#cb15-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;addLogging ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; [&lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;] &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-2&#34;&gt;&lt;a href=&#34;#cb15-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;addLogging x y &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-3&#34;&gt;&lt;a href=&#34;#cb15-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (x &lt;span class=&#34;op&#34;&gt;+&lt;/span&gt; y, [&lt;span class=&#34;st&#34;&gt;&amp;quot;Adding &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; x &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot; to &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; y &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;])&lt;/span&gt;
&lt;span id=&#34;cb15-4&#34;&gt;&lt;a href=&#34;#cb15-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-5&#34;&gt;&lt;a href=&#34;#cb15-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;multLogging ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; [&lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;] &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-6&#34;&gt;&lt;a href=&#34;#cb15-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;multLogging x y &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-7&#34;&gt;&lt;a href=&#34;#cb15-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (x &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; y, [&lt;span class=&#34;st&#34;&gt;&amp;quot;Multiplying &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; x &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot; with &amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; y &lt;span class=&#34;op&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;addLogging&lt;/code&gt;と&lt;code&gt;multLogging&lt;/code&gt;はそれぞれ、引数として受け取った整数を足し算したりかけ算したりしつつ、「足したよ」「かけたよ」という内容の文字列を一緒に返します。&lt;code&gt;Writer [String] Int&lt;/code&gt;における&lt;code&gt;[String]&lt;/code&gt;にログとして書き込んでいるようなイメージで捉えてください。&lt;/p&gt;
&lt;p&gt;これらを&lt;code&gt;do&lt;/code&gt;の中で使ってみると、より&lt;code&gt;addLogging&lt;/code&gt;や&lt;code&gt;multLogging&lt;/code&gt;が「足し算やかけ算をするついでに、ログとして書き込んでいる」っぽいイメージが伝わるでしょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb16&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb16-1&#34;&gt;&lt;a href=&#34;#cb16-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;testDo ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; [&lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;] &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-2&#34;&gt;&lt;a href=&#34;#cb16-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;testDo &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-3&#34;&gt;&lt;a href=&#34;#cb16-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  result1 &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; addLogging &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-4&#34;&gt;&lt;a href=&#34;#cb16-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  result2 &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; multLogging &lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-5&#34;&gt;&lt;a href=&#34;#cb16-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  addLogging result1 result2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;small&gt;⚠️申し訳なくも&lt;code&gt;do&lt;/code&gt;記法自体の解説、つまり&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;がどのように&lt;code&gt;do&lt;/code&gt;記法に対応するかはここには書きません。お近くの&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;入門書をご覧ください。&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;👆では、&lt;code&gt;3 + 4&lt;/code&gt;した結果&lt;code&gt;result1&lt;/code&gt;と、&lt;code&gt;5 * 2&lt;/code&gt;した結果&lt;code&gt;result2&lt;/code&gt;を足す処理を行っています。それに加えて、「足したよ」「かけたよ」というログを表す文字列のリスト&lt;code&gt;[String]&lt;/code&gt;も一緒に返しています。&lt;code&gt;do&lt;/code&gt;記法が&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;に変換されるのに従い、&lt;code&gt;Writer&lt;/code&gt;の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;が内部で&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;を使い、&lt;code&gt;addLogging 3 4&lt;/code&gt;・&lt;code&gt;multLogging 5 2&lt;/code&gt;・&lt;code&gt;addLogging result1 result2&lt;/code&gt;が返した文字列のリスト&lt;code&gt;[String]&lt;/code&gt;を結合することによって、あたかも&lt;code&gt;addLogging&lt;/code&gt;や&lt;code&gt;multLogging&lt;/code&gt;が「値を返しつつ、ログとして書き込む」かのような処理を実現できるのが&lt;code&gt;Writer&lt;/code&gt;における&lt;code&gt;do&lt;/code&gt;記法の特徴です。&lt;/p&gt;
&lt;!-- ReadmeTest: CompareAfterPrompt ByExpression --&gt;
&lt;p&gt;能書きはここまでにして、実際にどのような結果になるか見てみましょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb17&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb17-1&#34;&gt;&lt;a href=&#34;#cb17-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; runWriter testDo&lt;/span&gt;
&lt;span id=&#34;cb17-2&#34;&gt;&lt;a href=&#34;#cb17-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;(&lt;span class=&#34;dv&#34;&gt;17&lt;/span&gt;,[&lt;span class=&#34;st&#34;&gt;&amp;quot;Adding 3 to 4.&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;Multiplying 5 with 2.&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;Adding 7 to 10.&amp;quot;&lt;/span&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;はい、&lt;code&gt;3 + 4&lt;/code&gt;と&lt;code&gt;5 * 2&lt;/code&gt;の結果を足し算した結果&lt;code&gt;17&lt;/code&gt;と、&lt;code&gt;addLogging 3 4&lt;/code&gt;・&lt;code&gt;multLogging 5 2&lt;/code&gt;・&lt;code&gt;addLogging result1 result2&lt;/code&gt;が一緒に返していた文字列のリスト&lt;code&gt;[String]&lt;/code&gt;が、書いた順番どおりに結合されて返ってきました。&lt;code&gt;Writer&lt;/code&gt;は&lt;code&gt;do&lt;/code&gt;記法の中に書いた&lt;code&gt;Writer&lt;/code&gt;の値&lt;code&gt;(a, w)&lt;/code&gt;のうち、&lt;code&gt;Monoid&lt;/code&gt;のインスタンスである&lt;code&gt;w&lt;/code&gt;を&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;で都度結合させているということが伝わったでしょうか？&lt;/p&gt;
&lt;h2 id=&#34;writer-monadの結合則とmonoidの結合則&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#writer-monadの結合則とmonoidの結合則&#34; title=&#34;writer-monadの結合則とmonoidの結合則&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;code&gt;Writer&lt;/code&gt; &lt;code&gt;Monad&lt;/code&gt;の結合則と&lt;code&gt;Monoid&lt;/code&gt;の結合則&lt;/h2&gt;
&lt;p&gt;ここまでで、&lt;code&gt;Writer&lt;/code&gt; &lt;code&gt;Monad&lt;/code&gt;がどのように&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;を使っているのか、それによって&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;や&lt;code&gt;do&lt;/code&gt;記法がどのように振る舞っているのか、具体例を示して説明いたしました。ここからは、&lt;code&gt;Writer&lt;/code&gt;が&lt;code&gt;Monoid&lt;/code&gt;の&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;の結合則をどう利用することで、&lt;code&gt;Monad&lt;/code&gt;としての&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則を満たしているのかを示しましょう。長いので「めんどい！」という方は&lt;a href=&#34;#associative-law-qed&#34;&gt;こちらをクリックしてスキップ&lt;/a&gt;してください。&lt;/p&gt;
&lt;p&gt;そのために、&lt;code&gt;Monad&lt;/code&gt;の結合則における&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;を、&lt;code&gt;Writer&lt;/code&gt;の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;として展開してみます。&lt;/p&gt;
&lt;!-- ReadmeTest: Ignore --&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(0)&lt;/span&gt; &lt;code&gt;Monad&lt;/code&gt;の結合則&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb18&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb18-1&#34;&gt;&lt;a href=&#34;#cb18-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;m &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (m &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x)) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(1)&lt;/span&gt; &lt;code&gt;m&lt;/code&gt;は&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の左辺なので&lt;code&gt;Writer (a, w1)&lt;/code&gt;に置き換える&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;※ここからは、比較しやすくするために等式&lt;code&gt;=&lt;/code&gt;の左辺と右辺を別々の行に書きます。&lt;/small&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb19&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb19-1&#34;&gt;&lt;a href=&#34;#cb19-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h)&lt;/span&gt;
&lt;span id=&#34;cb19-2&#34;&gt;&lt;a href=&#34;#cb19-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-3&#34;&gt;&lt;a href=&#34;#cb19-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(2)&lt;/span&gt; 一つ目の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;を&lt;code&gt;Writer&lt;/code&gt;における&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の定義で置き換える&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb20&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb20-1&#34;&gt;&lt;a href=&#34;#cb20-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb20-2&#34;&gt;&lt;a href=&#34;#cb20-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h) a&lt;/span&gt;
&lt;span id=&#34;cb20-3&#34;&gt;&lt;a href=&#34;#cb20-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;
&lt;span id=&#34;cb20-4&#34;&gt;&lt;a href=&#34;#cb20-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-5&#34;&gt;&lt;a href=&#34;#cb20-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(3)&lt;/span&gt; 等式&lt;code&gt;=&lt;/code&gt;の右辺における一つ目の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;も同様に変換する&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb21&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb21-1&#34;&gt;&lt;a href=&#34;#cb21-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb21-2&#34;&gt;&lt;a href=&#34;#cb21-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h) a&lt;/span&gt;
&lt;span id=&#34;cb21-3&#34;&gt;&lt;a href=&#34;#cb21-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;
&lt;span id=&#34;cb21-4&#34;&gt;&lt;a href=&#34;#cb21-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb21-5&#34;&gt;&lt;a href=&#34;#cb21-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb21-6&#34;&gt;&lt;a href=&#34;#cb21-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (\x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; k x) a&lt;/span&gt;
&lt;span id=&#34;cb21-7&#34;&gt;&lt;a href=&#34;#cb21-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(4)&lt;/span&gt; 無名関数である&lt;code&gt;(\x -&amp;gt; k x &amp;gt;&amp;gt;= h)&lt;/code&gt;と&lt;code&gt;(\x -&amp;gt; k x)&lt;/code&gt;に、&lt;code&gt;a&lt;/code&gt;を適用する&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb22&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb22-1&#34;&gt;&lt;a href=&#34;#cb22-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb22-2&#34;&gt;&lt;a href=&#34;#cb22-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h&lt;/span&gt;
&lt;span id=&#34;cb22-3&#34;&gt;&lt;a href=&#34;#cb22-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;
&lt;span id=&#34;cb22-4&#34;&gt;&lt;a href=&#34;#cb22-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb22-5&#34;&gt;&lt;a href=&#34;#cb22-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb22-6&#34;&gt;&lt;a href=&#34;#cb22-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb22-7&#34;&gt;&lt;a href=&#34;#cb22-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(5)&lt;/span&gt; 等式&lt;code&gt;=&lt;/code&gt;の左辺における二つ目の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;を&lt;code&gt;Writer&lt;/code&gt;における&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の定義で置き換える&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb23&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb23-1&#34;&gt;&lt;a href=&#34;#cb23-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb23-2&#34;&gt;&lt;a href=&#34;#cb23-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb23-3&#34;&gt;&lt;a href=&#34;#cb23-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb23-4&#34;&gt;&lt;a href=&#34;#cb23-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (d, w4) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h c&lt;/span&gt;
&lt;span id=&#34;cb23-5&#34;&gt;&lt;a href=&#34;#cb23-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (d, w3 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w4)&lt;/span&gt;
&lt;span id=&#34;cb23-6&#34;&gt;&lt;a href=&#34;#cb23-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;
&lt;span id=&#34;cb23-7&#34;&gt;&lt;a href=&#34;#cb23-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb23-8&#34;&gt;&lt;a href=&#34;#cb23-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb23-9&#34;&gt;&lt;a href=&#34;#cb23-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb23-10&#34;&gt;&lt;a href=&#34;#cb23-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(6)&lt;/span&gt; 等式&lt;code&gt;=&lt;/code&gt;の右辺における二つ目の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;も同様に変換する&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb24&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb24-1&#34;&gt;&lt;a href=&#34;#cb24-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb24-2&#34;&gt;&lt;a href=&#34;#cb24-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb24-3&#34;&gt;&lt;a href=&#34;#cb24-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb24-4&#34;&gt;&lt;a href=&#34;#cb24-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (d, w4) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h c&lt;/span&gt;
&lt;span id=&#34;cb24-5&#34;&gt;&lt;a href=&#34;#cb24-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (d, w3 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w4)&lt;/span&gt;
&lt;span id=&#34;cb24-6&#34;&gt;&lt;a href=&#34;#cb24-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;
&lt;span id=&#34;cb24-7&#34;&gt;&lt;a href=&#34;#cb24-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb24-8&#34;&gt;&lt;a href=&#34;#cb24-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb24-9&#34;&gt;&lt;a href=&#34;#cb24-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb24-10&#34;&gt;&lt;a href=&#34;#cb24-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;
&lt;span id=&#34;cb24-11&#34;&gt;&lt;a href=&#34;#cb24-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (d, w4) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h c&lt;/span&gt;
&lt;span id=&#34;cb24-12&#34;&gt;&lt;a href=&#34;#cb24-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;     &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; (d, w3 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w4)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(7)&lt;/span&gt; &lt;code&gt;Writer&lt;/code&gt;は、&lt;code&gt;Writer&lt;/code&gt;と&lt;code&gt;(a, w)&lt;/code&gt;を切り替えるだけで実質何もしていないので削除する&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb25&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb25-1&#34;&gt;&lt;a href=&#34;#cb25-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb25-2&#34;&gt;&lt;a href=&#34;#cb25-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb25-3&#34;&gt;&lt;a href=&#34;#cb25-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb25-4&#34;&gt;&lt;a href=&#34;#cb25-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          (d, w4) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h c&lt;/span&gt;
&lt;span id=&#34;cb25-5&#34;&gt;&lt;a href=&#34;#cb25-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (d, w3 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w4)&lt;/span&gt;
&lt;span id=&#34;cb25-6&#34;&gt;&lt;a href=&#34;#cb25-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;
&lt;span id=&#34;cb25-7&#34;&gt;&lt;a href=&#34;#cb25-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb25-8&#34;&gt;&lt;a href=&#34;#cb25-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb25-9&#34;&gt;&lt;a href=&#34;#cb25-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb25-10&#34;&gt;&lt;a href=&#34;#cb25-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;
&lt;span id=&#34;cb25-11&#34;&gt;&lt;a href=&#34;#cb25-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        (d, w4) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h c&lt;/span&gt;
&lt;span id=&#34;cb25-12&#34;&gt;&lt;a href=&#34;#cb25-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;     &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (d, w3 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w4)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(7.5) (7)&lt;/span&gt;の等式をよく見ると、&lt;code&gt;=&lt;/code&gt;の左辺においては&lt;code&gt;(b, w2)&lt;/code&gt;と&lt;code&gt;(d, w3 &amp;lt;&amp;gt; w4)&lt;/code&gt;が、&lt;code&gt;=&lt;/code&gt;の右辺においては&lt;code&gt;(c, w3)&lt;/code&gt;と&lt;code&gt;(b, w1 &amp;lt;&amp;gt; w2)&lt;/code&gt;が等しい。&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb26&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb26-1&#34;&gt;&lt;a href=&#34;#cb26-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb26-2&#34;&gt;&lt;a href=&#34;#cb26-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;--           ここの(b, w2)は、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb26-3&#34;&gt;&lt;a href=&#34;#cb26-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb26-4&#34;&gt;&lt;a href=&#34;#cb26-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          (d, w4) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h c&lt;/span&gt;
&lt;span id=&#34;cb26-5&#34;&gt;&lt;a href=&#34;#cb26-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (d, w3 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w4) &lt;span class=&#34;co&#34;&gt;-- ここの(d, w3 &amp;lt;&amp;gt; w4)を代入したもの！&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb26-6&#34;&gt;&lt;a href=&#34;#cb26-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2)&lt;/span&gt;
&lt;span id=&#34;cb26-7&#34;&gt;&lt;a href=&#34;#cb26-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb26-8&#34;&gt;&lt;a href=&#34;#cb26-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb26-9&#34;&gt;&lt;a href=&#34;#cb26-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb26-10&#34;&gt;&lt;a href=&#34;#cb26-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (b, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2) &lt;span class=&#34;co&#34;&gt;-- ここで代入している！&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb26-11&#34;&gt;&lt;a href=&#34;#cb26-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        (d, w4) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h c&lt;/span&gt;
&lt;span id=&#34;cb26-12&#34;&gt;&lt;a href=&#34;#cb26-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;     &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (d, w3 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w4)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(8) (7.5)&lt;/span&gt;から、&lt;code&gt;=&lt;/code&gt;の左辺では&lt;code&gt;b = d&lt;/code&gt;で&lt;code&gt;w2 = w3 &amp;lt;&amp;gt; w4&lt;/code&gt;、&lt;code&gt;=&lt;/code&gt;の右辺では&lt;code&gt;c = d&lt;/code&gt;で&lt;code&gt;w3 = w1 &amp;lt;&amp;gt; w2&lt;/code&gt;であることがわかる。なのでそれぞれ置き換える&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb27&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb27-1&#34;&gt;&lt;a href=&#34;#cb27-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb27-2&#34;&gt;&lt;a href=&#34;#cb27-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb27-3&#34;&gt;&lt;a href=&#34;#cb27-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (d, w4) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h c&lt;/span&gt;
&lt;span id=&#34;cb27-4&#34;&gt;&lt;a href=&#34;#cb27-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (d, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; (w3 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w4))&lt;/span&gt;
&lt;span id=&#34;cb27-5&#34;&gt;&lt;a href=&#34;#cb27-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb27-6&#34;&gt;&lt;a href=&#34;#cb27-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb27-7&#34;&gt;&lt;a href=&#34;#cb27-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb27-8&#34;&gt;&lt;a href=&#34;#cb27-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (d, w4) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h b&lt;/span&gt;
&lt;span id=&#34;cb27-9&#34;&gt;&lt;a href=&#34;#cb27-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (d, (w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2) &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w4)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div id=&#34;associative-law-qed&#34;&gt;

&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;(9)&lt;/span&gt; &lt;code&gt;a&lt;/code&gt;～&lt;code&gt;d&lt;/code&gt;・&lt;code&gt;w1&lt;/code&gt;～&lt;code&gt;w4&lt;/code&gt;の変数名を、登場した順番に振り直す&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb28&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb28-1&#34;&gt;&lt;a href=&#34;#cb28-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb28-2&#34;&gt;&lt;a href=&#34;#cb28-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb28-3&#34;&gt;&lt;a href=&#34;#cb28-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h b&lt;/span&gt;
&lt;span id=&#34;cb28-4&#34;&gt;&lt;a href=&#34;#cb28-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (c, w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; (w2 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w3))&lt;/span&gt;
&lt;span id=&#34;cb28-5&#34;&gt;&lt;a href=&#34;#cb28-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb28-6&#34;&gt;&lt;a href=&#34;#cb28-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; (a, w1) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&#34;cb28-7&#34;&gt;&lt;a href=&#34;#cb28-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (b, w2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; k a&lt;/span&gt;
&lt;span id=&#34;cb28-8&#34;&gt;&lt;a href=&#34;#cb28-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    (c, w3) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; h b&lt;/span&gt;
&lt;span id=&#34;cb28-9&#34;&gt;&lt;a href=&#34;#cb28-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt; &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; (c, (w1 &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w2) &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; w3)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;等式&lt;code&gt;=&lt;/code&gt;の左辺と右辺がそっくりな式になりましたね！&lt;/p&gt;
&lt;p&gt;ここで、&lt;code&gt;Monoid&lt;/code&gt;の結合則を思い出してみましょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb29&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb29-1&#34;&gt;&lt;a href=&#34;#cb29-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;x &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; (y &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; z) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (x &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; y) &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; z&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;そう、&lt;code&gt;x &amp;lt;&amp;gt; y &amp;lt;&amp;gt; z&lt;/code&gt;などと書いて&lt;span class=&#34;ascii&#34;&gt;3&lt;/span&gt;つの&lt;code&gt;Monoid&lt;/code&gt;型クラスのインスタンスの値を&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;でくっつけるときは、カッコで囲って&lt;code&gt;(y &amp;lt;&amp;gt; z)&lt;/code&gt;を先に計算しようと、&lt;code&gt;(x &amp;lt;&amp;gt; y)&lt;/code&gt;を先に計算しようと、結果が変わらない、というものでした！&lt;/p&gt;
&lt;p&gt;それを踏まえて、&lt;span class=&#34;ascii&#34;&gt;(9)&lt;/span&gt;の等式&lt;code&gt;=&lt;/code&gt;の両辺をよく見比べてみてください。異なっているのは&lt;code&gt;w1 &amp;lt;&amp;gt; (w2 &amp;lt;&amp;gt; w3)&lt;/code&gt;と&lt;code&gt;(w1 &amp;lt;&amp;gt; w2) &amp;lt;&amp;gt; w3)&lt;/code&gt;の箇所だけですね！つまり、&lt;code&gt;Writer&lt;/code&gt; &lt;code&gt;Monad&lt;/code&gt;における&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則は、&lt;code&gt;w1 &amp;lt;&amp;gt; (w2 &amp;lt;&amp;gt; w3)&lt;/code&gt;と&lt;code&gt;(w1 &amp;lt;&amp;gt; w2) &amp;lt;&amp;gt; w3)&lt;/code&gt;が等しいから、すなわち&lt;code&gt;Monoid&lt;/code&gt;における&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;の結合則が成り立つからこそ成立するのです。これがまさしく「&lt;code&gt;Monoid&lt;/code&gt;と&lt;code&gt;Writer&lt;/code&gt;の切っても切り離せない関係」なのです！&lt;/p&gt;
&lt;h1 id=&#34;関係を壊してみる&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#関係を壊してみる&#34; title=&#34;関係を壊してみる&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;関係を壊してみる&lt;/h1&gt;
&lt;p&gt;それではいよいよ、「&lt;code&gt;Monoid&lt;/code&gt;と&lt;code&gt;Writer&lt;/code&gt;の切っても切り離せない関係」を利用して、&lt;code&gt;Monad&lt;/code&gt;則を破ってみましょう💣&lt;/p&gt;
&lt;h2 id=&#34;とmonoidの結合則&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#とmonoidの結合則&#34; title=&#34;とmonoidの結合則&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;と&lt;code&gt;Monoid&lt;/code&gt;の結合則&lt;/h2&gt;
&lt;p&gt;前述のとおり、&lt;code&gt;Writer&lt;/code&gt;における&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;が結合則を満たすのは、&lt;code&gt;Writer&lt;/code&gt;がラップしている&lt;code&gt;Monoid&lt;/code&gt;な値の&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;が結合則を満たしてこそ、なのでした。これは言い換えれば、その、ラップしている&lt;code&gt;Monoid&lt;/code&gt;な値の&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;が結合則を破れば、自然に&lt;code&gt;Writer&lt;/code&gt;の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;も結合則を破るはずです。この方法は、結合則を満たさない&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;っぽい処理をゼロから探すより遥かに簡単です。&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;のような&lt;code&gt;m a -&amp;gt; (a -&amp;gt; m b) -&amp;gt; m b&lt;/code&gt;というややこしい型の関数よりも、&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;のような&lt;code&gt;a -&amp;gt; a -&amp;gt; a&lt;/code&gt;という型の関数の方がずっと身近ですしね！&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Monoid&lt;/code&gt;の&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;のような&lt;code&gt;a -&amp;gt; a -&amp;gt; a&lt;/code&gt;という型の関数で、結合則を満たさない処理 — といえば、引き算&lt;code&gt;-&lt;/code&gt;や割り算&lt;code&gt;/&lt;/code&gt;を思い浮かべる方が多いのではないでしょうか。と、いうわけで&lt;a href=&#34;#monoid-examples&#34;&gt;&lt;code&gt;Monoid&lt;/code&gt;の例&lt;/a&gt;で紹介した&lt;code&gt;Sum&lt;/code&gt;や&lt;code&gt;Product&lt;/code&gt;のように、数値に対する引き算を表す&lt;code&gt;newtype&lt;/code&gt;、&lt;code&gt;Difference&lt;/code&gt;を定義してみましょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;!-- ReadmeTest: AppendAsIs --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb30&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb30-1&#34;&gt;&lt;a href=&#34;#cb30-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; {&lt;span class=&#34;ot&#34;&gt; getDifference ::&lt;/span&gt; a }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;それから、&lt;code&gt;Difference&lt;/code&gt;を&lt;small&gt;（実際には間違いですが）&lt;/small&gt;&lt;code&gt;Monoid&lt;/code&gt;のインスタンスにします。最近の&lt;span class=&#34;ascii&#34;&gt;GHC&lt;/span&gt;では、&lt;code&gt;Monoid&lt;/code&gt;のインスタンスを定義する前に&lt;code&gt;Semigroup&lt;/code&gt;のインスタンスにする必要があるのでご注意ください。説明しやすさのために敢えてこれまで触れてきませんでしたが、これまで何度も使った&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;は実際のところ&lt;code&gt;Monoid&lt;/code&gt;の関数ではなく&lt;code&gt;Semigroup&lt;/code&gt;の関数なんですね。&lt;code&gt;Monoid&lt;/code&gt;は「&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;で（結合則を備えた）二項演算ができるだけでなく、&lt;code&gt;mempty&lt;/code&gt;という単位元もある」という性質の型クラスなので、「単に『&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;で（結合則を備えた）二項演算ができる』だけの型クラスも欲しい！」というニーズから、&lt;code&gt;Monoid&lt;/code&gt;の&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;は&lt;code&gt;Semigroup&lt;/code&gt;の関数となり、&lt;code&gt;Monoid&lt;/code&gt;は&lt;code&gt;Semigroup&lt;/code&gt;のサブクラスという関係に変わったのでした。&lt;/p&gt;
&lt;p&gt;何はともあれ、&lt;code&gt;Difference&lt;/code&gt;を&lt;code&gt;Semigroup&lt;/code&gt;のインスタンスにしましょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb31&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb31-1&#34;&gt;&lt;a href=&#34;#cb31-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Num&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Semigroup&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; a) &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb31-2&#34;&gt;&lt;a href=&#34;#cb31-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; a &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; b &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; (a &lt;span class=&#34;op&#34;&gt;-&lt;/span&gt; b)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;はい、単に両辺を&lt;code&gt;-&lt;/code&gt;で引き算するだけですね。&lt;/p&gt;
&lt;p&gt;今度こそ&lt;code&gt;Difference&lt;/code&gt;を&lt;code&gt;Monoid&lt;/code&gt;のインスタンスにします。本記事では&lt;code&gt;mempty&lt;/code&gt;を直接使うことはないので何でもいいはずですが、とりあえず&lt;code&gt;Sum&lt;/code&gt;と同様に&lt;code&gt;0&lt;/code&gt;ということにしておきます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb32&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb32-1&#34;&gt;&lt;a href=&#34;#cb32-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Num&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Monoid&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; a) &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb32-2&#34;&gt;&lt;a href=&#34;#cb32-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;mempty&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;😈これで&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;が結合則を満たさないおかしな&lt;code&gt;Monoid&lt;/code&gt;のインスタンス、&lt;code&gt;Difference&lt;/code&gt;ができました！早速試して結合則を破っていることを確認してみましょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;!-- ReadmeTest: CompareAfterPrompt ByExpression --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb33&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb33-1&#34;&gt;&lt;a href=&#34;#cb33-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらは 1 - (2 - 3) と同じ&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb33-2&#34;&gt;&lt;a href=&#34;#cb33-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getDifference &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb33-3&#34;&gt;&lt;a href=&#34;#cb33-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb33-4&#34;&gt;&lt;a href=&#34;#cb33-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb33-5&#34;&gt;&lt;a href=&#34;#cb33-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらは (1 - 2) - 3 と同じなので...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb33-6&#34;&gt;&lt;a href=&#34;#cb33-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getDifference &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;) &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb33-7&#34;&gt;&lt;a href=&#34;#cb33-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;-- &amp;lt;- 当然 1 - (2 - 3) とは異なる結果に！&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;バッチリ破れてますね！このように&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;における結合則は、引き算などおなじみの演算で、簡単に破ることができます💪&lt;/p&gt;
&lt;h2 id=&#34;とmonadの結合則&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#とmonadの結合則&#34; title=&#34;とmonadの結合則&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;と&lt;code&gt;Monad&lt;/code&gt;の結合則&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;における結合則を破ることができたと言うことは、&lt;code&gt;Writer&lt;/code&gt;の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;による結合則も、もはや破れたも同然です。先ほど定義した&lt;code&gt;Difference&lt;/code&gt;型を使えば、&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;は途端に結合則を満たさなくなるでしょう。&lt;/p&gt;
&lt;p&gt;例を示す前に、&lt;code&gt;Writer&lt;/code&gt;を使う際しばしば用いられる、ユーティリティー関数を定義しておきます。実践で&lt;code&gt;Writer&lt;/code&gt;を使いたくなったときにも大変便利なので、是非覚えておいてください&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;!-- ReadmeTest: AppendAsIs --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb34&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb34-1&#34;&gt;&lt;a href=&#34;#cb34-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;tell ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Monoid&lt;/span&gt; w &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; w &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; w ()&lt;/span&gt;
&lt;span id=&#34;cb34-2&#34;&gt;&lt;a href=&#34;#cb34-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;tell w &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Writer&lt;/span&gt; ((), w)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この&lt;code&gt;tell&lt;/code&gt;関数は、受け取った&lt;code&gt;Monoid&lt;/code&gt;な値をそのまま「ログとして書き込む」関数です。結果として返す値はただのユニット&lt;code&gt;()&lt;/code&gt;なので、気にする必要がありません。&lt;code&gt;tell&lt;/code&gt;のみを使って&lt;code&gt;Writer&lt;/code&gt;を組み立てれば、「ログとして書き込む」値のみに集中することができます。これから紹介する例でもやはり関心があるのは「ログとして書き込む」値だけなので、ここで&lt;code&gt;tell&lt;/code&gt;を定義しました。&lt;/p&gt;
&lt;p&gt;それでは&lt;code&gt;tell&lt;/code&gt;を使って、&lt;code&gt;Writer&lt;/code&gt;の&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;における結合則も破ってみましょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;!-- ReadmeTest: CompareAfterPrompt ByExpression --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb35&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb35-1&#34;&gt;&lt;a href=&#34;#cb35-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらは Difference 1 &amp;lt;&amp;gt; (Difference 2 &amp;lt;&amp;gt; Difference 3) と同じ&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb35-2&#34;&gt;&lt;a href=&#34;#cb35-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getDifference &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;snd&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; runWriter &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)))&lt;/span&gt;
&lt;span id=&#34;cb35-3&#34;&gt;&lt;a href=&#34;#cb35-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb35-4&#34;&gt;&lt;a href=&#34;#cb35-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb35-5&#34;&gt;&lt;a href=&#34;#cb35-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらは (Difference 1 &amp;lt;&amp;gt; Difference 2) &amp;lt;&amp;gt; Difference 3 と同じなので...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb35-6&#34;&gt;&lt;a href=&#34;#cb35-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getDifference &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;snd&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; runWriter &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; (tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;))) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&#34;cb35-7&#34;&gt;&lt;a href=&#34;#cb35-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;-- &amp;lt;- 当然 1 - (2 - 3) とは異なる結果に！&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;予想どおり一つ目の&lt;code&gt;Writer&lt;/code&gt;と二つ目の&lt;code&gt;Writer&lt;/code&gt;とで異なる結果となりました。&lt;code&gt;1 - (2 - 3)&lt;/code&gt;と&lt;code&gt;(1 - 2) - 3&lt;/code&gt;を&lt;code&gt;Writer&lt;/code&gt;を使って遠回しに言い換えているだけなので、当然と言えば当然です。&lt;/p&gt;
&lt;p&gt;しかし&lt;code&gt;tell (Difference 1) &amp;gt;&amp;gt;= (\_ -&amp;gt; tell (Difference 2) &amp;gt;&amp;gt;= \_ -&amp;gt; tell (Difference 3))&lt;/code&gt;などの&lt;code&gt;Writer&lt;/code&gt;型の式が&lt;code&gt;Monad&lt;/code&gt;の結合則&lt;code&gt;m &amp;gt;&amp;gt;= (\x -&amp;gt; k x &amp;gt;&amp;gt;= h) = (m &amp;gt;&amp;gt;= (\x -&amp;gt; k x)) &amp;gt;&amp;gt;= h&lt;/code&gt;にどう対応するのか、ちょっと分かりづらいですかね？&lt;small&gt;（式も長いし）&lt;/small&gt;一つずつ注釈を加えます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb36&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb36-1&#34;&gt;&lt;a href=&#34;#cb36-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらは m &amp;gt;&amp;gt;= (\x -&amp;gt; k x &amp;gt;&amp;gt;= h) = (m &amp;gt;&amp;gt;= (\x -&amp;gt; k x)) &amp;gt;&amp;gt;= h の前半、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb36-2&#34;&gt;&lt;a href=&#34;#cb36-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--   m &amp;gt;&amp;gt;= (\x -&amp;gt; k x &amp;gt;&amp;gt;= h) に相当する&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb36-3&#34;&gt;&lt;a href=&#34;#cb36-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)))&lt;/span&gt;
&lt;span id=&#34;cb36-4&#34;&gt;&lt;a href=&#34;#cb36-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- ^^^^^^^^^^^^^^^^^^^       ^    ^^^^^^^^^^^^^^^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb36-5&#34;&gt;&lt;a href=&#34;#cb36-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--          m                x             k                             h&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb36-6&#34;&gt;&lt;a href=&#34;#cb36-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb36-7&#34;&gt;&lt;a href=&#34;#cb36-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb36-8&#34;&gt;&lt;a href=&#34;#cb36-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらは m &amp;gt;&amp;gt;= (\x -&amp;gt; k x &amp;gt;&amp;gt;= h) = (m &amp;gt;&amp;gt;= (\x -&amp;gt; k x)) &amp;gt;&amp;gt;= h の後半、&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb36-9&#34;&gt;&lt;a href=&#34;#cb36-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--   (m &amp;gt;&amp;gt;= (\x -&amp;gt; k x)) &amp;gt;&amp;gt;= h に相当する&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb36-10&#34;&gt;&lt;a href=&#34;#cb36-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt;  (tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;))) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&#34;cb36-11&#34;&gt;&lt;a href=&#34;#cb36-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--  ^^^^^^^^^^^^^^^^^^^       ^    ^^^^^^^^^^^^^^^^^^^       ^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb36-12&#34;&gt;&lt;a href=&#34;#cb36-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;--           m                x             k                             h&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ラムダ式の引数&lt;code&gt;x&lt;/code&gt;は実際には使われていない点に注意してください。これでも&lt;code&gt;const&lt;/code&gt;を使って&lt;code&gt;\x -&amp;gt; const (tell (Difference 2)) x&lt;/code&gt;と書き換えれば、&lt;code&gt;const (tell (Difference 2))&lt;/code&gt;が&lt;code&gt;k&lt;/code&gt;に厳密に対応するので、上記の二組の式は&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則を破るペアだと言えます。&lt;/p&gt;
&lt;h2 id=&#34;do記法とmonadの結合則&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#do記法とmonadの結合則&#34; title=&#34;do記法とmonadの結合則&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;code&gt;do&lt;/code&gt;記法と&lt;code&gt;Monad&lt;/code&gt;の結合則&lt;/h2&gt;
&lt;p&gt;前の節では、&lt;code&gt;Monoid&lt;/code&gt;の結合則を守っていない値をラップしている&lt;code&gt;Writer&lt;/code&gt;を作ることで、&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則を破る例を簡単に作り出せることを紹介しました。ここでは本記事の最後として、&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則を破った結果、&lt;code&gt;do&lt;/code&gt;記法がいかに直感に反する挙動となるか紹介して、&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則を守ることが私たちにどのようなメリットをもたらすのか解説します。&lt;/p&gt;
&lt;p&gt;例として、先ほど&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則を破るのに使った&lt;code&gt;1 - 2 - 3&lt;/code&gt;を再利用しましょう。&lt;code&gt;Difference&lt;/code&gt;をラップした&lt;code&gt;Writer&lt;/code&gt;で&lt;code&gt;1 - 2 - 3&lt;/code&gt;を計算させると、次のような式になります&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;!-- ReadmeTest: ValidateAsExpression --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb37&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb37-1&#34;&gt;&lt;a href=&#34;#cb37-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)) &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; (\_ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これを&lt;code&gt;do&lt;/code&gt;記法に変換すると、次のようになります&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb38&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb38-1&#34;&gt;&lt;a href=&#34;#cb38-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb38-2&#34;&gt;&lt;a href=&#34;#cb38-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb38-3&#34;&gt;&lt;a href=&#34;#cb38-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb38-4&#34;&gt;&lt;a href=&#34;#cb38-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;do&lt;/code&gt;記法における各行の間に&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;が隠れたことで、すっきりしましたね！&lt;/p&gt;
&lt;p&gt;この状態から、&lt;code&gt;do&lt;/code&gt;記法を使って&lt;code&gt;1 - (2 - 3)&lt;/code&gt;と&lt;code&gt;(1 - 2) - 3&lt;/code&gt;を表す&lt;code&gt;Writer&lt;/code&gt;の式にするには、次のように書き換えます&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;!-- ReadmeTest: AppendAsIs --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb39&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb39-1&#34;&gt;&lt;a href=&#34;#cb39-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらが 1 - (2 - 3) を表す&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb39-2&#34;&gt;&lt;a href=&#34;#cb39-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;do_1minus&amp;#39;2minus3&amp;#39; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb39-3&#34;&gt;&lt;a href=&#34;#cb39-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb39-4&#34;&gt;&lt;a href=&#34;#cb39-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb39-5&#34;&gt;&lt;a href=&#34;#cb39-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb39-6&#34;&gt;&lt;a href=&#34;#cb39-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb39-7&#34;&gt;&lt;a href=&#34;#cb39-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb39-8&#34;&gt;&lt;a href=&#34;#cb39-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb39-9&#34;&gt;&lt;a href=&#34;#cb39-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらが (1 - 2) - 3 を表す&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb39-10&#34;&gt;&lt;a href=&#34;#cb39-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;do_&amp;#39;1minus2&amp;#39;minus3 &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb39-11&#34;&gt;&lt;a href=&#34;#cb39-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb39-12&#34;&gt;&lt;a href=&#34;#cb39-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb39-13&#34;&gt;&lt;a href=&#34;#cb39-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb39-14&#34;&gt;&lt;a href=&#34;#cb39-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb39-15&#34;&gt;&lt;a href=&#34;#cb39-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;コメントに書いたとおり、&lt;code&gt;do_1minus&#39;2minus3&#39;&lt;/code&gt;が&lt;code&gt;1 - (2 - 3)&lt;/code&gt;、&lt;code&gt;do_&#39;1minus2&#39;minus3&lt;/code&gt;が&lt;code&gt;(1 - 2) - 3&lt;/code&gt;と同等な&lt;code&gt;Writer&lt;/code&gt;です。&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;はシングルクォートを変数の名前に含めることができるので、シングルクォートでカッコを表すことにしました&lt;small&gt;（まさかこんなところで役に立つとはね！）&lt;/small&gt;。&lt;/p&gt;
&lt;p&gt;上記の二つの式では、カッコ&lt;code&gt;()&lt;/code&gt;で囲う代わりにもう一つの&lt;code&gt;do&lt;/code&gt;記法に収めることで、&lt;code&gt;do&lt;/code&gt;記法における各行を実行する順番をいじっています。&lt;/p&gt;
&lt;p&gt;本当にこれで&lt;code&gt;1 - (2 - 3)&lt;/code&gt;や&lt;code&gt;(1 - 2) - 3&lt;/code&gt;と同等な式になっているのでしょうか？試しに&lt;code&gt;runWriter&lt;/code&gt;して結果を確かめてみましょう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;!-- ReadmeTest: CompareAfterPrompt ByExpression --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb40&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb40-1&#34;&gt;&lt;a href=&#34;#cb40-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらが 1 - (2 - 3) を表す&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb40-2&#34;&gt;&lt;a href=&#34;#cb40-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getDifference &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;snd&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; runWriter do_1minus&amp;#39;2minus3&amp;#39;&lt;/span&gt;
&lt;span id=&#34;cb40-3&#34;&gt;&lt;a href=&#34;#cb40-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb40-4&#34;&gt;&lt;a href=&#34;#cb40-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb40-5&#34;&gt;&lt;a href=&#34;#cb40-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;-- こちらが (1 - 2) - 3 を表す&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb40-6&#34;&gt;&lt;a href=&#34;#cb40-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&lt;/span&gt; getDifference &lt;span class=&#34;op&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;snd&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; runWriter do_&amp;#39;1minus2&amp;#39;minus3&lt;/span&gt;
&lt;span id=&#34;cb40-7&#34;&gt;&lt;a href=&#34;#cb40-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;バッチリ👌想定どおり、&lt;code&gt;do_1minus&#39;2minus3&#39;&lt;/code&gt;が&lt;code&gt;1 - (2 - 3) = 2&lt;/code&gt;を計算し、&lt;code&gt;do_&#39;1minus2&#39;minus3&lt;/code&gt;が&lt;code&gt;(1 - 2) - 3 = -4&lt;/code&gt;を計算していますね！&lt;/p&gt;
&lt;p&gt;さてこれまでで、&lt;code&gt;Writer&lt;/code&gt; &lt;code&gt;Monad&lt;/code&gt;は&lt;code&gt;Monoid&lt;/code&gt;の結合則を利用することで&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則を満たしていることを示し、ラップしている&lt;code&gt;Monoid&lt;/code&gt;な値が結合則を満たしていなければ、必然的に&lt;code&gt;Writer&lt;/code&gt;も結合則を破ってしまうことを、&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;や&lt;code&gt;do&lt;/code&gt;記法を使って具体的に示しました。それでは今挙げた、&lt;code&gt;do&lt;/code&gt;記法で結合則を破った例は、一体何を示唆しているのでしょうか？普通に&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;でコードを書いていて、前述のような書き換え、すなわち、&lt;/p&gt;
&lt;!-- ReadmeTest: ValidateAsExpression --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb41&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb41-1&#34;&gt;&lt;a href=&#34;#cb41-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb41-2&#34;&gt;&lt;a href=&#34;#cb41-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb41-3&#34;&gt;&lt;a href=&#34;#cb41-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb41-4&#34;&gt;&lt;a href=&#34;#cb41-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb41-5&#34;&gt;&lt;a href=&#34;#cb41-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;から、&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb42&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb42-1&#34;&gt;&lt;a href=&#34;#cb42-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-2&#34;&gt;&lt;a href=&#34;#cb42-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-3&#34;&gt;&lt;a href=&#34;#cb42-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb42-4&#34;&gt;&lt;a href=&#34;#cb42-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb42-5&#34;&gt;&lt;a href=&#34;#cb42-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;への書き換え&lt;small&gt;（あるいはその逆）&lt;/small&gt;は、一見するとそんな機会ないように思えます。しかしこれが、&lt;code&gt;do&lt;/code&gt;記法をカッコ代わりに使うという変な方法ではなく、次のように変数に代入することで切り出していた場合、いかがでしょうか？&lt;/p&gt;
&lt;!-- ReadmeTest: AppendAsIs --&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb43&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb43-1&#34;&gt;&lt;a href=&#34;#cb43-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;someSingleAction &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb43-2&#34;&gt;&lt;a href=&#34;#cb43-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb43-3&#34;&gt;&lt;a href=&#34;#cb43-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;someSequence &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb43-4&#34;&gt;&lt;a href=&#34;#cb43-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb43-5&#34;&gt;&lt;a href=&#34;#cb43-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb43-6&#34;&gt;&lt;a href=&#34;#cb43-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb43-7&#34;&gt;&lt;a href=&#34;#cb43-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;someCompositeAction &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb43-8&#34;&gt;&lt;a href=&#34;#cb43-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  someSingleAction&lt;/span&gt;
&lt;span id=&#34;cb43-9&#34;&gt;&lt;a href=&#34;#cb43-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  someSequence&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;上記👆のような三つの&lt;code&gt;Writer&lt;/code&gt;の値を、下記👇の三つの値にリファクタリングする場合です。&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb44&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb44-1&#34;&gt;&lt;a href=&#34;#cb44-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;refactoredSequence &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb44-2&#34;&gt;&lt;a href=&#34;#cb44-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb44-3&#34;&gt;&lt;a href=&#34;#cb44-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb44-4&#34;&gt;&lt;a href=&#34;#cb44-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb44-5&#34;&gt;&lt;a href=&#34;#cb44-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;splitOutSingleAction &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb44-6&#34;&gt;&lt;a href=&#34;#cb44-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb44-7&#34;&gt;&lt;a href=&#34;#cb44-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;refactoredCompositeAction &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb44-8&#34;&gt;&lt;a href=&#34;#cb44-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  refactoredSequence&lt;/span&gt;
&lt;span id=&#34;cb44-9&#34;&gt;&lt;a href=&#34;#cb44-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  splitOutSingleAction&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;あるいは、たった&lt;span class=&#34;ascii&#34;&gt;3&lt;/span&gt;行しかありませんし、一つの値に統合する方がいいかも知れません&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb45&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb45-1&#34;&gt;&lt;a href=&#34;#cb45-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;flattenedAction &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb45-2&#34;&gt;&lt;a href=&#34;#cb45-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb45-3&#34;&gt;&lt;a href=&#34;#cb45-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb45-4&#34;&gt;&lt;a href=&#34;#cb45-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  tell (&lt;span class=&#34;dt&#34;&gt;Difference&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これらの書き換えは、いずれも&lt;code&gt;do&lt;/code&gt;記法が内部で使っている&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則を前提とすれば、可能であってしかるべきです。&lt;code&gt;do&lt;/code&gt;記法は、適当に&lt;code&gt;Monad&lt;/code&gt;のインスタンスの値（「アクション」などとも呼ばれます）を上から下まで列挙すれば、自動で&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;を使ってつなげてくれる、というものです。なので、適当に並べたアクションがどういう形に結合されるのか気にする必要があるのでは、安心して使えません。一方、上記の&lt;span class=&#34;ascii&#34;&gt;3&lt;/span&gt;組の式は、&lt;code&gt;Writer Difference&lt;/code&gt;、すなわち引き算を表す「偽&lt;code&gt;Monoid&lt;/code&gt;」をラップしているが故に、&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;の結合則を満たしておりません。結果、&lt;code&gt;do&lt;/code&gt;記法に変えたときに並べたアクションをどこで切り出すかで、結果が変わってしまいます。これでは安心して列挙できません！&lt;/p&gt;
&lt;!-- ReadmeTest: CompareAfterPrompt ByExpression --&gt;
&lt;!--
```haskell
&gt; getDifference . snd $ runWriter someCompositeAction
2
&gt; getDifference . snd $ runWriter refactoredCompositeAction
-4
&gt; getDifference . snd $ runWriter flattenedAction
2
```
--&gt;
&lt;h1 id=&#34;まとめ&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#まとめ&#34; title=&#34;まとめ&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;まとめ&lt;/h1&gt;
&lt;p&gt;以上です。これまでで、&lt;code&gt;Monad&lt;/code&gt;則のうち結合則がなぜ重要なのか、結合則を実際に破ってみることを通じて説明しました。&lt;code&gt;Monad&lt;/code&gt;と同様に結合則を持った&lt;code&gt;Monoid&lt;/code&gt;は、&lt;code&gt;Monad&lt;/code&gt;以上にインスタンスを見つけるのが簡単で、なおかつ、例えば引き算のように「二項演算だけど結合則を満たしていない」処理を見つけるのが簡単です。本記事では&lt;code&gt;Monoid&lt;/code&gt;のそうした性質と、&lt;code&gt;Monoid&lt;/code&gt;の性質でもって&lt;code&gt;Monad&lt;/code&gt;則を満たしている&lt;code&gt;Writer&lt;/code&gt; &lt;code&gt;Monad&lt;/code&gt;に注目することで、簡単に&lt;code&gt;Monad&lt;/code&gt;則を破る例を提示することができました。それから、&lt;code&gt;Monad&lt;/code&gt;の結合則を実際に破った例を使って、&lt;code&gt;Monad&lt;/code&gt;の結合則が&lt;code&gt;do&lt;/code&gt;記法を自然に書けるようにするために必要であることを示しました。これらの実例から主張したいことを一般化すると、次のとおりです&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;do&lt;/code&gt;記法の各行の間で、値を返すついでに何かを行うのが&lt;code&gt;Monad&lt;/code&gt;のインスタンス&lt;/li&gt;
&lt;li&gt;&lt;code&gt;do&lt;/code&gt;記法の各行の間で、値を返すついでに行っている処理が結合則を満たす型が、&lt;code&gt;Monad&lt;/code&gt;則を満たすと言える&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Monad&lt;/code&gt;則を守らない型を&lt;code&gt;do&lt;/code&gt;記法で使うと、&lt;code&gt;do&lt;/code&gt;記法の結合を気にして書かなければならなくなる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それでは、&lt;span class=&#34;ascii&#34;&gt;2021&lt;/span&gt;年も🎁&lt;span class=&#34;ascii&#34;&gt;Happy Haskell Hacking with Monad&lt;/span&gt;🎁&lt;span class=&#34;ascii&#34;&gt;!&lt;/span&gt;&lt;/p&gt;
&lt;section id=&#34;footnotes&#34; class=&#34;footnotes footnotes-end-of-document&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn1&#34;&gt;&lt;p&gt;一応、&lt;code&gt;Monad&lt;/code&gt;についてはそのスーパークラスである&lt;code&gt;Applicative&lt;/code&gt;の則、&lt;code&gt;Functor&lt;/code&gt;の則がありますが、&lt;code&gt;Monad&lt;/code&gt;則を満たしていればそれらは自動的に満たせるので、ここでは省略します。&lt;a href=&#34;#fnref1&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn2&#34;&gt;&lt;p&gt;残念ながら実際のところ、&lt;code&gt;Float&lt;/code&gt;型・&lt;code&gt;Double&lt;/code&gt;型などの浮動小数点数に対する&lt;code&gt;Sum&lt;/code&gt;や&lt;code&gt;Product&lt;/code&gt;は結合則を満たさない場合があります。これは他の多くのプログラミング言語にもある、浮動小数点数の悩ましい問題です。詳しくは「情報落ち」で検索してみてください。&lt;a href=&#34;#fnref2&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn3&#34;&gt;&lt;p&gt;ここでの定義は、実際に使われている&lt;a href=&#34;http://hackage.haskell.org/package/transformers&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;transformers&lt;/span&gt;パッケージ&lt;/a&gt;の&lt;code&gt;Writer&lt;/code&gt;の定義とは大きく異なっているのでご注意ください。実際の&lt;code&gt;Writer&lt;/code&gt;はパフォーマンス上の都合や&lt;span class=&#34;ascii&#34;&gt;Monad Transformer&lt;/span&gt;との兼ね合いで、幾分工夫された定義となっています。&lt;a href=&#34;#fnref3&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
                &lt;i class=&#34;glyphicon glyphicon-chevron-left&#34; aria-hidden=&#34;true&#34; style=&#34;margin-right: 5px;&#34;&gt;&lt;/i&gt;
                &lt;a href=&#34;/posts/about_admins.html&#34; lang=&#34;ja&#34;&gt;日本Haskellユーザーグループ管理委員会（Haskell-jp Admins）設立のお知らせ&lt;/a&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/2020/antenna-with-gh-actions.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;Haskell AntennaのCI/CDをGitHub Actionsに移行する&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&gt;

</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2020/12/18/214626</id><title type="text">動的配列の無難なHaskell実装</title><updated>2020-12-18T21:46:26+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2020/12/18/214626"/><summary type="html">qiita.com C++、Rust、Pythonなど、他の言語では当たり前のように多用される動的配列だが、Haskell実装は(開発を始めた時点では)見当たらなかったので作ってみたお話*1。 動的配列とはミュータブルな配列の一種で、通常の配列操作だけでなく、末尾への要素の追加・削除が定数時間で行える構造である。確保しておいた領域がいっぱいになったら、その2倍の大きさの領域を確保するという方法によって、漸近的には要素の追加は定数時間となる。 内部の配列には、デファクトスタンダードであるvectorパッケージを用いる。Vectorには無印(boxed)、Unboxed、Storableの三種類の…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2020/12/16/004851</id><title type="text">liszt: Append onlyでリーダーとライターが分離されたKVS</title><updated>2020-12-16T00:48:51+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2020/12/16/004851"/><summary type="html">adventar.org 以前仕事で使おうとして没になったアイデアを改めて記事にまとめる。 動機 以前書いた記事で説明したものとほとんど一緒である。 fumieval.hatenablog.com プログラムのログをリアルタイムに監視する仕組みが欲しいが、その仕組みがダウンしても監視対象には影響を及ぼさないようにしたいというのポイントだ。 そのため、ライター側はファイルに書き込み、リーダーはinotifyなどでファイルを監視するという、書き込みにサーバーを必要としない仕組みにした。 さらに、途中でクラッシュしても問題ないよう、ファイルはappend-onlyとし、ファイルの最後にページを書き込…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/12/13/%E3%81%A8%E3%82%8A%E3%81%A8%E3%82%81%E3%81%AE%E3%81%AA%E3%81%84_GHC_%E7%B7%9A%E5%BD%A2%E5%9E%8B%E3%83%A1%E3%83%A2</id><title type="text">とりとめのない GHC 線形型メモ</title><updated>2020-12-13T18:56:45+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/12/13/%E3%81%A8%E3%82%8A%E3%81%A8%E3%82%81%E3%81%AE%E3%81%AA%E3%81%84_GHC_%E7%B7%9A%E5%BD%A2%E5%9E%8B%E3%83%A1%E3%83%A2"/><summary type="html">GHC 9.0.1 alpha 1 がリリースされたときに線形型をいじってみていたことをメモしていなかったので思い出しながらメモしていく。 mail.haskell.org 使用バージョン GHC 9.0.0.20200925 上記リンクのもの ghcup ならそれ経由でインストールできる。 ghcups の場合は手動インストール後、下記のような設定ファイルで切り替えができるようになる1。 ghc: 9.0.1-alpha1: H:\programs\ghc-9.0.0.20200925-x86_64-unknown-mingw32\bin 線形型とは GHC では引数が1回しか使えない（1回…</summary></entry><entry><id>https://haskell.jp/blog/posts/2020/antenna-with-gh-actions.html</id><title type="text">Haskell AntennaのCI/CDをGitHub Actionsに移行する</title><updated>2020-12-12T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/2020/antenna-with-gh-actions.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;hr /&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell-jp&lt;/span&gt;のコンテンツの一つとして&lt;a href=&#34;https://haskell.jp/antenna/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell Antenna&lt;/span&gt;&lt;/a&gt;という&lt;span class=&#34;ascii&#34;&gt;Web&lt;/span&gt;ページの開発・運用をしております。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../img/2020/antenna-with-gh-actions/antenna-page.jpg&#34; style=&#34;width: 100%;&#34;&gt;&lt;/p&gt;
&lt;p&gt;バイナリのビルドや&lt;span class=&#34;ascii&#34;&gt;Docker&lt;/span&gt;イメージのビルドに&lt;span class=&#34;ascii&#34;&gt;TravisCI&lt;/span&gt;を、バイナリを実行してページの更新をするのに&lt;span class=&#34;ascii&#34;&gt;DroneCI&lt;/span&gt;を使っていました。
しかし、長らく放置していてちゃんと動作しているか怪しかったので、メンテナンスをするついでに昨今はやり（要出典）の&lt;a href=&#34;https://github.com/haskell-jp/antenna/pull/26&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;GitHub Actions&lt;/span&gt;にこれらを移行することにしました&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../img/2020/antenna-with-gh-actions/pr.jpg&#34; style=&#34;width: 100%;&#34;&gt;&lt;/p&gt;
&lt;div id=&#34;table-of-contents-outer&#34;&gt;
&lt;div id=&#34;table-of-contents&#34;&gt;
&lt;div class=&#34;table-of-contents-title&#34;&gt;
Contents
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#stackプロジェクトのビルド&#34; title=&#34;stackプロジェクトのビルド&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Stack&lt;/span&gt;プロジェクトのビルド&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#dockerイメージのビルドとプッシュ&#34; title=&#34;dockerイメージのビルドとプッシュ&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Docker&lt;/span&gt;イメージのビルドとプッシュ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#antennaプログラムの実行&#34; title=&#34;antennaプログラムの実行&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;antenna&lt;/span&gt;プログラムの実行&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;stackプロジェクトのビルド&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#stackプロジェクトのビルド&#34; title=&#34;stackプロジェクトのビルド&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;Stack&lt;/span&gt;プロジェクトのビルド&lt;/h3&gt;
&lt;p&gt;まずはバイナリのビルドを行うように設定します。
&lt;span class=&#34;ascii&#34;&gt;Haskell Antenna&lt;/span&gt;のプログラムは&lt;span class=&#34;ascii&#34;&gt;Haskell Stack&lt;/span&gt;を利用しているので、&lt;code&gt;stack build&lt;/code&gt;が実行できれば良いです。&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode yaml&#34;&gt;&lt;code class=&#34;sourceCode yaml&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Build Application&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;pull_request&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ch&#34;&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-4&#34;&gt;&lt;a href=&#34;#cb1-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-5&#34;&gt;&lt;a href=&#34;#cb1-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;branches&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-6&#34;&gt;&lt;a href=&#34;#cb1-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; master&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-7&#34;&gt;&lt;a href=&#34;#cb1-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-8&#34;&gt;&lt;a href=&#34;#cb1-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-9&#34;&gt;&lt;a href=&#34;#cb1-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ${{ matrix.os }}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-10&#34;&gt;&lt;a href=&#34;#cb1-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ubuntu-18.04&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-11&#34;&gt;&lt;a href=&#34;#cb1-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;strategy&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-12&#34;&gt;&lt;a href=&#34;#cb1-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;fail-fast&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ch&#34;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-13&#34;&gt;&lt;a href=&#34;#cb1-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;matrix&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-14&#34;&gt;&lt;a href=&#34;#cb1-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;ghc&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;8.8.4&amp;quot;&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-15&#34;&gt;&lt;a href=&#34;#cb1-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-16&#34;&gt;&lt;a href=&#34;#cb1-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; actions/checkout@v2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-17&#34;&gt;&lt;a href=&#34;#cb1-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Cache .stack&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-18&#34;&gt;&lt;a href=&#34;#cb1-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; cache-stack&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-19&#34;&gt;&lt;a href=&#34;#cb1-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; actions/cache@v2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-20&#34;&gt;&lt;a href=&#34;#cb1-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-21&#34;&gt;&lt;a href=&#34;#cb1-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ~/.stack&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-22&#34;&gt;&lt;a href=&#34;#cb1-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-23&#34;&gt;&lt;a href=&#34;#cb1-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;          ${{ runner.os }}-stack\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-24&#34;&gt;&lt;a href=&#34;#cb1-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;          -${{ hashFiles(&amp;#39;**/stack.yaml.lock&amp;#39;) }}\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-25&#34;&gt;&lt;a href=&#34;#cb1-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;          -${{ hashFiles(&amp;#39;**/package.yaml&amp;#39;) }}\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-26&#34;&gt;&lt;a href=&#34;#cb1-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;        &amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-27&#34;&gt;&lt;a href=&#34;#cb1-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;        restore-keys&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;ch&#34;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-28&#34;&gt;&lt;a href=&#34;#cb1-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          ${{ runner.os }}-stack-&lt;/span&gt;
&lt;span id=&#34;cb1-29&#34;&gt;&lt;a href=&#34;#cb1-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; haskell/actions/setup@main&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-30&#34;&gt;&lt;a href=&#34;#cb1-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Setup Haskell&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-31&#34;&gt;&lt;a href=&#34;#cb1-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-32&#34;&gt;&lt;a href=&#34;#cb1-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;ghc-version&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ${{ matrix.ghc }}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-33&#34;&gt;&lt;a href=&#34;#cb1-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;enable-stack&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ch&#34;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-34&#34;&gt;&lt;a href=&#34;#cb1-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;stack-version&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-35&#34;&gt;&lt;a href=&#34;#cb1-35&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Install dependencies&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-36&#34;&gt;&lt;a href=&#34;#cb1-36&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; stack --system-ghc test --only-dependencies&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-37&#34;&gt;&lt;a href=&#34;#cb1-37&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Build and Test&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-38&#34;&gt;&lt;a href=&#34;#cb1-38&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; stack --system-ghc test --copy-bins --local-bin-path=./bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは、&lt;span class=&#34;ascii&#34;&gt;PR&lt;/span&gt;が作られたときや&lt;span class=&#34;ascii&#34;&gt;master&lt;/span&gt;がプッシュされたときに実行されることを想定しています。&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;GitHub Actions&lt;/span&gt;で&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt;や&lt;span class=&#34;ascii&#34;&gt;Haskell Stack&lt;/span&gt;を使うには、&lt;del&gt;公式が提供している&lt;a href=&#34;https://github.com/actions/setup-haskell&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;actions/setup-haskell&lt;/span&gt;&lt;/a&gt;&lt;/del&gt; &lt;a href=&#34;https://github.com/haskell/actions/tree/main/setup&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;haskell/actions/setup&lt;/span&gt;&lt;/a&gt; を利用します。
元々は&lt;span class=&#34;ascii&#34;&gt;actions/haskell-setup&lt;/span&gt;がありましたが、どうやら&lt;a href=&#34;https://github.com/actions/setup-haskell/pull/56&#34;&gt;メンテナンスする人がいなくなったっぽく&lt;/a&gt;アーカイブされてしまいました。
この記事を書いている時点では移行したばかりでちゃんとタグが切られていないため、&lt;span class=&#34;ascii&#34;&gt;main&lt;/span&gt;ブランチを指定しています。
ちなみに、&lt;span class=&#34;ascii&#34;&gt;Stack&lt;/span&gt;プロジェクトの&lt;span class=&#34;ascii&#34;&gt;GHC&lt;/span&gt;バージョンを&lt;span class=&#34;ascii&#34;&gt;haskell/actions/setup&lt;/span&gt;でインストールして、&lt;code&gt;stack --system-ghc&lt;/code&gt;をすることでキャッシュサイズを減らすことができます。&lt;/p&gt;
&lt;p&gt;これまた余談ですが、&lt;span class=&#34;ascii&#34;&gt;actions/setup-haskell&lt;/span&gt;の方を使っていて次のようなエラーが出る場合は&lt;span class=&#34;ascii&#34;&gt;actions/setup-haskell&lt;/span&gt;のバージョンが古いです（&lt;a href=&#34;https://github.com/actions/setup-haskell/issues/44&#34;&gt;最新では修正済みです&lt;/a&gt;）。&lt;span class=&#34;ascii&#34;&gt;haskell/actions/setup&lt;/span&gt;の方を使いましょう。&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;Installing&lt;/span&gt; ghc version 8.8.4&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;Error:&lt;/span&gt; Unable to process command &lt;span class=&#34;st&#34;&gt;&amp;#39;::add-path::/opt/ghc/8.8.4/bin&amp;#39;&lt;/span&gt; successfully.&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;Error:&lt;/span&gt; The &lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;ex&#34;&gt;add-path&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt; command is disabled. Please upgrade to using Environment Files or opt into unsecure command execution by setting the &lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;ex&#34;&gt;ACTIONS_ALLOW_UNSECURE_COMMANDS&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt; environment variable to &lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt;. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;dockerイメージのビルドとプッシュ&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#dockerイメージのビルドとプッシュ&#34; title=&#34;dockerイメージのビルドとプッシュ&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;Docker&lt;/span&gt;イメージのビルドとプッシュ&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://hub.docker.com/r/haskelljp/antenna/&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;antenna&lt;/span&gt;プログラムは&lt;span class=&#34;ascii&#34;&gt;Docker&lt;/span&gt;イメージにして&lt;span class=&#34;ascii&#34;&gt;Docker Hub&lt;/span&gt;に置いてあります&lt;/a&gt;（これも&lt;span class=&#34;ascii&#34;&gt;GitHub Container Registry&lt;/span&gt;に移行したいですね）。
なので、&lt;span class=&#34;ascii&#34;&gt;master&lt;/span&gt;の更新に合わせて&lt;span class=&#34;ascii&#34;&gt;Docker&lt;/span&gt;イメージをビルドしてプッシュするジョブを設定します。
&lt;span class=&#34;ascii&#34;&gt;Docker&lt;/span&gt;イメージのビルドとプッシュには&lt;a href=&#34;https://github.com/docker/build-push-action&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;docker/build-push-action&lt;/span&gt;&lt;/a&gt;を使います。&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode yaml&#34;&gt;&lt;code class=&#34;sourceCode yaml&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# さっきと同じ設定ファイルです&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-2&#34;&gt;&lt;a href=&#34;#cb3-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Build Application&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-3&#34;&gt;&lt;a href=&#34;#cb3-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-4&#34;&gt;&lt;a href=&#34;#cb3-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;pull_request&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ch&#34;&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-5&#34;&gt;&lt;a href=&#34;#cb3-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-6&#34;&gt;&lt;a href=&#34;#cb3-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;branches&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-7&#34;&gt;&lt;a href=&#34;#cb3-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; master&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-8&#34;&gt;&lt;a href=&#34;#cb3-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-9&#34;&gt;&lt;a href=&#34;#cb3-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-10&#34;&gt;&lt;a href=&#34;#cb3-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ${{ matrix.os }}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-11&#34;&gt;&lt;a href=&#34;#cb3-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ubuntu-18.04&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-12&#34;&gt;&lt;a href=&#34;#cb3-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;strategy&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-13&#34;&gt;&lt;a href=&#34;#cb3-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;fail-fast&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ch&#34;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-14&#34;&gt;&lt;a href=&#34;#cb3-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;matrix&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-15&#34;&gt;&lt;a href=&#34;#cb3-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;ghc&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;8.8.4&amp;quot;&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-16&#34;&gt;&lt;a href=&#34;#cb3-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-17&#34;&gt;&lt;a href=&#34;#cb3-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    ...&lt;/span&gt;&lt;span class=&#34;co&#34;&gt; # 割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-18&#34;&gt;&lt;a href=&#34;#cb3-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Build and Test&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-19&#34;&gt;&lt;a href=&#34;#cb3-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; stack --system-ghc test --copy-bins --local-bin-path=./bin&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-20&#34;&gt;&lt;a href=&#34;#cb3-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;    # Build and Push Docker Image&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-21&#34;&gt;&lt;a href=&#34;#cb3-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Setup QEMU&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-22&#34;&gt;&lt;a href=&#34;#cb3-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; docker/setup-qemu-action@master&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-23&#34;&gt;&lt;a href=&#34;#cb3-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-24&#34;&gt;&lt;a href=&#34;#cb3-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;platforms&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; all&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-25&#34;&gt;&lt;a href=&#34;#cb3-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Setup Docker Buildx&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-26&#34;&gt;&lt;a href=&#34;#cb3-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; buildx&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-27&#34;&gt;&lt;a href=&#34;#cb3-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; docker/setup-buildx-action@master&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-28&#34;&gt;&lt;a href=&#34;#cb3-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-29&#34;&gt;&lt;a href=&#34;#cb3-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; latest&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-30&#34;&gt;&lt;a href=&#34;#cb3-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Login to DockerHub&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-31&#34;&gt;&lt;a href=&#34;#cb3-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; docker/login-action@v1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-32&#34;&gt;&lt;a href=&#34;#cb3-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-33&#34;&gt;&lt;a href=&#34;#cb3-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ${{ secrets.DOCKER_USERNAME }}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-34&#34;&gt;&lt;a href=&#34;#cb3-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;password&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ${{ secrets.DOCKERHUB_TOKEN }}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-35&#34;&gt;&lt;a href=&#34;#cb3-35&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Build and push&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-36&#34;&gt;&lt;a href=&#34;#cb3-36&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; docker/build-push-action@v2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-37&#34;&gt;&lt;a href=&#34;#cb3-37&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-38&#34;&gt;&lt;a href=&#34;#cb3-38&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; .&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-39&#34;&gt;&lt;a href=&#34;#cb3-39&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;builder&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ${{ steps.buildx.outputs.name }}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-40&#34;&gt;&lt;a href=&#34;#cb3-40&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;tags&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; haskelljp/antenna:latest&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-41&#34;&gt;&lt;a href=&#34;#cb3-41&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ${{ github.event_name != &amp;#39;pull_request&amp;#39; }}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-42&#34;&gt;&lt;a href=&#34;#cb3-42&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;build-args&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; local_bin_path=./bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;master&lt;/span&gt;ブランチへのプッシュのときにだけ&lt;span class=&#34;ascii&#34;&gt;Docker&lt;/span&gt;イメージのプッシュをして欲しいので、&lt;code&gt;push:&lt;/code&gt; に &lt;code&gt;github.event_name != &#39;pull_request&#39;&lt;/code&gt; を設定しています。
また、&lt;span class=&#34;ascii&#34;&gt;Haskell Stack&lt;/span&gt;でビルドされたバイナリファイルは&lt;code&gt;--local-bin-path=./bin&lt;/code&gt;オプションで&lt;code&gt;./bin&lt;/code&gt;に置いてあります。
これを&lt;span class=&#34;ascii&#34;&gt;Dockerfile&lt;/span&gt;でコピーするようにしている（下記参照）ので、&lt;code&gt;docker build&lt;/code&gt;の引数に&lt;code&gt;local_bin_path=./bin&lt;/code&gt;というのを与える必要がありました。&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode dockerfile&#34;&gt;&lt;code class=&#34;sourceCode dockerfile&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;FROM&lt;/span&gt; matsubara0507/ubuntu-for-haskell:git&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;ARG&lt;/span&gt; local_bin_path&lt;/span&gt;
&lt;span id=&#34;cb4-3&#34;&gt;&lt;a href=&#34;#cb4-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;RUN&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;mkdir&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-p&lt;/span&gt; /root/.local/bin &lt;span class=&#34;kw&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;mkdir&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-p&lt;/span&gt; /work&lt;/span&gt;
&lt;span id=&#34;cb4-4&#34;&gt;&lt;a href=&#34;#cb4-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;ENV&lt;/span&gt; PATH /root/.local/bin:$PATH&lt;/span&gt;
&lt;span id=&#34;cb4-5&#34;&gt;&lt;a href=&#34;#cb4-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;WORKDIR&lt;/span&gt; /work&lt;/span&gt;
&lt;span id=&#34;cb4-6&#34;&gt;&lt;a href=&#34;#cb4-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;COPY&lt;/span&gt; ${local_bin_path} /root/.local/bin&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このように前の&lt;span class=&#34;ascii&#34;&gt;step&lt;/span&gt;までの結果を利用するには &lt;code&gt;context: .&lt;/code&gt; を指定する必要があります（デフォルトでは&lt;a href=&#34;https://github.com/docker/build-push-action/tree/v2#git-context&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;git-context&lt;/span&gt;&lt;/a&gt;というのを使うからです）。&lt;/p&gt;
&lt;h3 id=&#34;antennaプログラムの実行&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#antennaプログラムの実行&#34; title=&#34;antennaプログラムの実行&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&#34;ascii&#34;&gt;antenna&lt;/span&gt;プログラムの実行&lt;/h3&gt;
&lt;p&gt;最後に、&lt;span class=&#34;ascii&#34;&gt;master&lt;/span&gt;の更新があったときに&lt;span class=&#34;ascii&#34;&gt;antenna&lt;/span&gt;プログラムを実行して&lt;span class=&#34;ascii&#34;&gt;Haskell Antenna&lt;/span&gt;ページを更新するような設定をします。
日毎のスケジュール実行も設定したいので、新しいワークフローを切りました。&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode yaml&#34;&gt;&lt;code class=&#34;sourceCode yaml&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Update Antenna page&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-3&#34;&gt;&lt;a href=&#34;#cb5-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;schedule&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-4&#34;&gt;&lt;a href=&#34;#cb5-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;cron&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;0 8 * * *&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-5&#34;&gt;&lt;a href=&#34;#cb5-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-6&#34;&gt;&lt;a href=&#34;#cb5-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;branches&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-7&#34;&gt;&lt;a href=&#34;#cb5-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; master&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-8&#34;&gt;&lt;a href=&#34;#cb5-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;paths-ignore&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-9&#34;&gt;&lt;a href=&#34;#cb5-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;README.md&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-10&#34;&gt;&lt;a href=&#34;#cb5-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;CHANGELOG.md&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-11&#34;&gt;&lt;a href=&#34;#cb5-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;LICENSE&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-12&#34;&gt;&lt;a href=&#34;#cb5-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;.gitignore&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-13&#34;&gt;&lt;a href=&#34;#cb5-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-14&#34;&gt;&lt;a href=&#34;#cb5-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-15&#34;&gt;&lt;a href=&#34;#cb5-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ${{ matrix.os }}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-16&#34;&gt;&lt;a href=&#34;#cb5-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ubuntu-18.04&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-17&#34;&gt;&lt;a href=&#34;#cb5-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;strategy&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-18&#34;&gt;&lt;a href=&#34;#cb5-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;fail-fast&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ch&#34;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-19&#34;&gt;&lt;a href=&#34;#cb5-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;matrix&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-20&#34;&gt;&lt;a href=&#34;#cb5-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;ghc&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;8.8.4&amp;quot;&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-21&#34;&gt;&lt;a href=&#34;#cb5-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-22&#34;&gt;&lt;a href=&#34;#cb5-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    ...&lt;/span&gt;&lt;span class=&#34;co&#34;&gt; # Install dependenciesまでは一緒なので割愛&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-23&#34;&gt;&lt;a href=&#34;#cb5-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Build&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-24&#34;&gt;&lt;a href=&#34;#cb5-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; stack --system-ghc build&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-25&#34;&gt;&lt;a href=&#34;#cb5-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-26&#34;&gt;&lt;a href=&#34;#cb5-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; actions/checkout@v2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-27&#34;&gt;&lt;a href=&#34;#cb5-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-28&#34;&gt;&lt;a href=&#34;#cb5-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;gh-pages&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-29&#34;&gt;&lt;a href=&#34;#cb5-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;temp&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-30&#34;&gt;&lt;a href=&#34;#cb5-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Exec Application&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-31&#34;&gt;&lt;a href=&#34;#cb5-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;      run&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;ch&#34;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-32&#34;&gt;&lt;a href=&#34;#cb5-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        cp sites.yaml temp/sites.yaml&lt;/span&gt;
&lt;span id=&#34;cb5-33&#34;&gt;&lt;a href=&#34;#cb5-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        cp -r image/* temp/image&lt;/span&gt;
&lt;span id=&#34;cb5-34&#34;&gt;&lt;a href=&#34;#cb5-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        cd temp &amp;amp;&amp;amp; stack exec -- antenna sites.yaml&lt;/span&gt;
&lt;span id=&#34;cb5-35&#34;&gt;&lt;a href=&#34;#cb5-35&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Push changes&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-36&#34;&gt;&lt;a href=&#34;#cb5-36&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-37&#34;&gt;&lt;a href=&#34;#cb5-37&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;COMMIT_MESSAGE&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; Update haskell antenna. See https://haskell.jp/antenna/ for new entries!&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-38&#34;&gt;&lt;a href=&#34;#cb5-38&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;      run&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;ch&#34;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-39&#34;&gt;&lt;a href=&#34;#cb5-39&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        git config --local user.email &amp;quot;bot@example.com&amp;quot;&lt;/span&gt;
&lt;span id=&#34;cb5-40&#34;&gt;&lt;a href=&#34;#cb5-40&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        git config --local user.name &amp;quot;Bot&amp;quot;&lt;/span&gt;
&lt;span id=&#34;cb5-41&#34;&gt;&lt;a href=&#34;#cb5-41&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        git status&lt;/span&gt;
&lt;span id=&#34;cb5-42&#34;&gt;&lt;a href=&#34;#cb5-42&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        git add -A&lt;/span&gt;
&lt;span id=&#34;cb5-43&#34;&gt;&lt;a href=&#34;#cb5-43&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        git diff --staged --quiet || git commit -m &amp;quot;$COMMIT_MESSAGE&amp;quot;&lt;/span&gt;
&lt;span id=&#34;cb5-44&#34;&gt;&lt;a href=&#34;#cb5-44&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        git push origin gh-pages&lt;/span&gt;
&lt;span id=&#34;cb5-45&#34;&gt;&lt;a href=&#34;#cb5-45&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;at&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;working-directory&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;at&#34;&gt; ./temp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;バイナリをビルドするところまでは一緒です。
&lt;span class=&#34;ascii&#34;&gt;Haskell Antenna&lt;/span&gt;は同じリポジトリの&lt;span class=&#34;ascii&#34;&gt;gh-pages&lt;/span&gt;ブランチに置いて、&lt;span class=&#34;ascii&#34;&gt;GitHub Pages&lt;/span&gt;を使って公開しています。
なので、同じリポジトリの&lt;span class=&#34;ascii&#34;&gt;gh-pages&lt;/span&gt;ブランチを&lt;span class=&#34;ascii&#34;&gt;git clone&lt;/span&gt;しなおしてサブディレクトリに置き、そこで&lt;span class=&#34;ascii&#34;&gt;antenna&lt;/span&gt;プログラムを実行して、更新があった場合にのみプッシュしています。
同じリポジトリであれば、特に設定することなくプッシュできるのが&lt;span class=&#34;ascii&#34;&gt;GitHub Actions&lt;/span&gt;のメリットですね。&lt;/p&gt;
&lt;h2 id=&#34;おまけzennを追加しました&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#おまけzennを追加しました&#34; title=&#34;おまけzennを追加しました&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;おまけ：&lt;span class=&#34;ascii&#34;&gt;Zenn&lt;/span&gt;を追加しました！&lt;/h2&gt;
&lt;p&gt;ついでに最近のアップデートによって、&lt;a href=&#34;https://github.com/haskell-jp/antenna/pull/25&#34;&gt;&lt;span class=&#34;ascii&#34;&gt;Zenn&lt;/span&gt;を&lt;span class=&#34;ascii&#34;&gt;Haskell Antenna&lt;/span&gt;に載せるサイトへ追加しました&lt;/a&gt;（&lt;span class=&#34;ascii&#34;&gt;igrep&lt;/span&gt;氏がしてくれました、ありがとうございます）。
アイコンの利用規約などがわからなかったのですが、&lt;span class=&#34;ascii&#34;&gt;GitHub&lt;/span&gt;の&lt;span class=&#34;ascii&#34;&gt;PR&lt;/span&gt;上で直接聞いてみたところ、問題ないという回答をいただきました。
突然だったのにありがとうございます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../img/2020/antenna-with-gh-actions/antenna-page-with-zenn.jpg&#34; style=&#34;width: 100%;&#34;&gt;&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
                &lt;i class=&#34;glyphicon glyphicon-chevron-left&#34; aria-hidden=&#34;true&#34; style=&#34;margin-right: 5px;&#34;&gt;&lt;/i&gt;
                &lt;a href=&#34;/posts/2020/break-monad-law-with-writer.html&#34; lang=&#34;ja&#34;&gt;Writer Monadで気軽にMonad則を破る&lt;/a&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/2020/how-to-use-type-newtype-data.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;data / newtype / type の使い方&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&gt;

</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2020/12/02/181155</id><title type="text">Kubernetes: kube-scheduler をソースコードレベルで理解する</title><updated>2020-12-02T18:11:55+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2020/12/02/181155"/><summary type="html">はじめに Kubernetes において、Pod を配置するための Node を決定する手続きをスケジューリングと呼び、デフォルトのクラスタでは kube-scheduler がその責務を担っています。本記事ではこの kube-scheduler のソースコードを時系列に沿って追いつつ、どのようなロジックで Pod を配置する Node が決定されるのかを解説します。 なお、本記事は Kubernetes の内部実装について学ぶ勉強会 Kubernetes Internal #3 の補足資料を意図して執筆されました。本文中で参照しているソースコードのバージョンは v1.19.4 です。 Kub…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2020/11/14/214355</id><title type="text">安全性-活性分解定理とその関連研究</title><updated>2020-11-14T21:43:55+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2020/11/14/214355"/><summary type="html">こんにちは、チェシャ猫です。先日行われた第 7 回 Web System Architecture 研究会で形式手法について発表してきました。 普段、形式手法について登壇する際は具体例な検証例を出すことが多いですが、今回は理論側に寄せたサーベイになっています。 はじめに 本セッションでは、安全性-活性分解 (safety-liveness decomposition) と呼ばれる一連の結果について解説する。安全性-活性分解は、システムの仕様が与えられた時、それを安全性 (safety) および活性 (liveness) と呼ばれる、よりシンプルな特徴付けを持つクラスに分解して扱うための方法論で…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/11/03/Windows_%E3%81%8B%E3%82%89_Windows_%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%83%BC%E3%81%A8_Linux_%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%83%BC%E3%81%AE%E4%B8%A1%E6%96%B9%E3%81%AE_Docker_%E3%82%92</id><title type="text">Windows から Windows コンテナーと Linux コンテナーの両方の Docker を使う</title><updated>2020-11-03T02:20:40+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/11/03/Windows_%E3%81%8B%E3%82%89_Windows_%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%83%BC%E3%81%A8_Linux_%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%83%BC%E3%81%AE%E4%B8%A1%E6%96%B9%E3%81%AE_Docker_%E3%82%92"/><summary type="html">Docker Desktop for Windows は Windows コンテナーと Linux コンテナーが使えるのだけど排他的になっている。 そう思ってスクショを取るために切り替えボタンを押してみたら今はそうじゃない？Windows/Linux コンテナーの切り替え、前は完全に排他的だったと思ったけど、今は実行は両方できるのか？あとホストの再起動要らなくなってる？ まあ、そもそも Docker Desktop for Windows のコンテナーが排他的なの理由が分からないのよな。 で、両方のコンテナーをいじりたいのでラッパープログラムを作った。その内要らなくなりそうだけど。 イメージ図…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/10/28/Data.Monoid.First_%E3%81%A8_Data.Semigroup.First_%E3%81%82%E3%82%8B%E3%81%84%E3%81%AF_Last</id><title type="text">Data.Monoid.First と Data.Semigroup.First あるいは Last</title><updated>2020-10-28T22:33:09+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/10/28/Data.Monoid.First_%E3%81%A8_Data.Semigroup.First_%E3%81%82%E3%82%8B%E3%81%84%E3%81%AF_Last"/><summary type="html">Data.Monoid.First のドキュメントを見ていたら次の記述を見つけたことから始まる記事です。 This type will be marked deprecated in GHC 8.8, and removed in GHC 8.10. Users are advised to use the variant from Data.Semigroup and wrap it in Maybe. すでに GHC 8.10 がリリースされているのにまだなくなっていない気がしますが（GHC 9.0.1-alpha1 にもまだある）、Data.Monoid.First よりも Data.S…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/10/23/%E5%8B%95%E7%9A%84%E5%9E%8B%E4%BB%98%E3%81%91%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%97%E3%83%AA%E3%82%BF%E3%83%BC%E8%A8%80%E8%AA%9E_Haskell</id><title type="text">動的型付けインタープリター言語 Haskell</title><updated>2020-10-23T18:16:01+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/10/23/%E5%8B%95%E7%9A%84%E5%9E%8B%E4%BB%98%E3%81%91%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%97%E3%83%AA%E3%82%BF%E3%83%BC%E8%A8%80%E8%AA%9E_Haskell"/><summary type="html">コンパイルを待つなんて生産性が低い！ 通らないコード片のエラーなんか知らない！ えっ？！まだ静的型検査してコンパイルしてるの？ デキるプログラマーは動的型検査！インタープリット！ main = do input &lt;- readLn if input &lt; 10 then putStrLn &#34;Hi&#34; else putStrLn (&#34;Bad&#34; + input) このコードを実行するにはどうしてる？まさかこうしてる？ &gt; ghc main.hs main.hs:5:21: error: • No instance for (Num [Char]) arising from a use of ‘+’ •…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2020/10/02/204554</id><title type="text">自動printfデバッグ</title><updated>2020-10-02T20:45:54+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2020/10/02/204554"/><summary type="html">関数をデバッグするために、引数と戻り値をそれぞれ表示するというのを誰しもやったことがあると思う。今回はそれを自動化するからくりをHaskellで実装してみる。 目標となるのは、関数が与えられたとき、その引数と結果をターミナルに出力する関数に変換する高階関数、probe :: Traceable a =&gt; String -&gt; a -&gt; aである。 testDelay :: Double -&gt; Double -&gt; IO () testDelay dur dur&#39; = threadDelay $ round $ (dur + dur&#39;) * 1000000 *Probe&gt; probe &#34;testDe…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/09/26/shake_%2B_lucid_%2B_hint_%E3%81%A7%E9%9D%99%E7%9A%84%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B5%E3%82%A4%E3%83%88%E7%94%9F%E6%88%90</id><title type="text">shake + lucid + hint で静的ウェブサイト生成</title><updated>2020-09-26T17:13:27+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/09/26/shake_%2B_lucid_%2B_hint_%E3%81%A7%E9%9D%99%E7%9A%84%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B5%E3%82%A4%E3%83%88%E7%94%9F%E6%88%90"/><summary type="html">The English version is at Dev. 同人活動用のウェブサイトがあって今までは Jekyll で生成していました。これを Shake + Lucid + Hint で作成した生成器に置き換えました。 doujin.kakkun61.com shakebuild.com hackage.haskell.org hackage.haskell.org ソースコードはこちらです。 github.com 経緯 GitHub Pages をホストに選択したので最初は自然に Jekyll を選びました。レールに乗っているうちはいいのですが外れたことをしようとすると難しくなってきまし…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2020/09/10/044848</id><title type="text">CloudNative Days Tokyo 2020 で CockroachDB と TLA+ について話してきました</title><updated>2020-09-10T04:48:48+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2020/09/10/044848"/><summary type="html">こんにちは、チェシャ猫です。先日行われた CloudNative Days Tokyo 2020 で、形式手法ツール TLA+ が CockroachDB の設計に使用された事例について発表してきました。公募 CFP 枠です。 講演概要 CockroachDB は、Google Spanner の系譜に連なるいわゆる NewSQL データベースの一種です。 強い一貫性や ACID トランザクションといった従来の関係データベースが持つ「良い特徴」を残したまま、従来の関係データベースが苦手としていた水平スケーリングにも優れるのが特徴です。CockroachDB 自身は「地理分散 (geo-dist…</summary></entry><entry><id>https://kakkun61.hatenablog.com/entry/2020/09/02/%E4%B8%80%E7%95%AA%E7%B0%A1%E5%8D%98%E3%81%AA_MonadFail_%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9</id><title type="text">一番簡単な MonadFail インスタンス</title><updated>2020-09-02T02:53:28+09:00</updated><author><name>岡本和樹</name></author><link href="https://kakkun61.hatenablog.com/entry/2020/09/02/%E4%B8%80%E7%95%AA%E7%B0%A1%E5%8D%98%E3%81%AA_MonadFail_%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9"/><summary type="html">The English version is at Dev. 導入 fail が Monad から剥がされて早や幾年、私は失敗する可能性のある計算は MonadFail を使って型を付けるのが好きです。 foo :: MonadFail m =&gt; m a こうすると IO の文脈であればその中で、純粋な文脈であれば Maybe などで具体化して呼ぶことができます。 -- IO の文脈では foo :: IO a -- 純粋な文脈では foo :: Maybe a さて、純粋な文脈として Maybe を使うと失敗のメッセージを失ってしまうことが嬉しくありません。では、Either を使えばいいの…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2020/07/30/173935</id><title type="text">【#CODT2020 解説】Infrastructure as Code の静的テスト戦略</title><updated>2020-07-30T17:39:35+09:00</updated><author><name>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2020/07/30/173935"/><summary type="html">こんにちは、チェシャ猫です。先日行われた Cloud Operator Days Tokyo 2020 で、Infrastructure as Code のテストについて発表してきました。公募 CFP 枠です。 Cloud Operator Days Tokyo 2020 は今回が初開催のイベントですが、昨年 CloudNative Days Tokyo と併設されていた OpenStack Days Tokyo が前身となっているようです。 ASCII.jp：ふれあえるオンラインイベント「Cloud Operator Days Tokyo 2020」は泥臭い？ 今年は OpenStack に…</summary></entry><entry><id>https://haskell.jp/blog/posts/2020/how-to-use-type-newtype-data.html</id><title type="text">data / newtype / type の使い方</title><updated>2020-06-14T00:00:00Z</updated><author><name>Haskell-jp</name></author><link href="https://haskell.jp/blog/posts/2020/how-to-use-type-newtype-data.html"/><summary type="html">
&lt;article lang=&#34;ja&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-8 col-md-offset-1 col-md-10&#34;&gt;
                &lt;ul class=&#34;social-buttons&#34;&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a href=&#34;https://twitter.com/share&#34; class=&#34;twitter-share-button&#34;&gt;Tweet&lt;/a&gt;
                        &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?&#39;http&#39;:&#39;https&#39;;if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+&#39;://platform.twitter.com/widgets.js&#39;;fjs.parentNode.insertBefore(js,fjs);}}(document, &#39;script&#39;, &#39;twitter-wjs&#39;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;
                            reddit_target = &#34;haskell_jp&#34;;
                            reddit_title  = document.title;
                        &lt;/script&gt;
                        &lt;script type=&#34;text/javascript&#34; src=&#34;//www.redditstatic.com/button/button1.js&#34;&gt;&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;div&gt;
                        &lt;a data-pocket-label=&#34;pocket&#34; data-pocket-count=&#34;horizontal&#34; class=&#34;pocket-btn&#34; data-lang=&#34;en&#34;&gt;&lt;/a&gt;
                        &lt;script type=&#34;text/javascript&#34;&gt;!function(d,i){if(!d.getElementById(i)){var j=d.createElement(&#34;script&#34;);j.id=i;j.src=&#34;https://widgets.getpocket.com/v1/j/btn.js?v=1&#34;;var w=d.getElementById(i);d.body.appendChild(j);}}(document,&#34;pocket-btn-js&#34;);&lt;/script&gt;
                    &lt;/div&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&#34;row&#34;&gt;
            &lt;div id=&#34;md-post-content&#34; class=&#34;col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1&#34;&gt;
              &lt;hr /&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; プログラミングにおいて，データ型は非常に重要な役割を持つ．データ型は，扱うデータをプログラミング上で安全かつ容易に加工するために用いられ，またデータに対してどのような操作ができるのかを規定する．&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; には，データ型を新たに定義する方法が&lt;span class=&#34;ascii&#34;&gt;3&lt;/span&gt;つある．&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つ目は &lt;code&gt;type&lt;/code&gt; キーワードによって定義する方法で，これにより定義されたデータ型は型シノニムと呼ばれる．&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つ目は &lt;code&gt;data&lt;/code&gt; キーワードによって定義する方法で，これにより定義されたデータ型は代数的データ型と呼ばれる．&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;ascii&#34;&gt;3&lt;/span&gt;つ目は &lt;code&gt;newtype&lt;/code&gt; キーワードによってある型を元に新たな型を作る方法だ．&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回は，それぞれどういう使い方をするのか，どういう違いがあるのかについて見ていきたいと思う．&lt;/p&gt;
&lt;div id=&#34;table-of-contents-outer&#34;&gt;
&lt;div id=&#34;table-of-contents&#34;&gt;
&lt;div class=&#34;table-of-contents-title&#34;&gt;
Contents
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#型シノニム&#34; title=&#34;型シノニム&#34;&gt;型シノニム&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#代数的データ型&#34; title=&#34;代数的データ型&#34;&gt;代数的データ型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#ある型を元に新たな型を作る-datatype-renaming&#34; title=&#34;ある型を元に新たな型を作る-datatype-renaming&#34;&gt;ある型を元に新たな型を作る &lt;span class=&#34;ascii&#34;&gt;(Datatype Renaming)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#まとめ&#34; title=&#34;まとめ&#34;&gt;まとめ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;型シノニム&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#型シノニム&#34; title=&#34;型シノニム&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;型シノニム&lt;/h2&gt;
&lt;p&gt;例えば，あなたは &lt;span class=&#34;ascii&#34;&gt;Web&lt;/span&gt; サイトを運営していて，一部年齢制限が必要なため，人の年齢が &lt;span class=&#34;ascii&#34;&gt;20&lt;/span&gt; 歳以上かを判定する関数を書かなければいけないとする．年齢は整数だが，入力は必須でないため入力してない人もいる．その場合は，&lt;span class=&#34;ascii&#34;&gt;20&lt;/span&gt; 歳以上でないと判定する．この関数は，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;isAdult ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;isAdult m &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt; m &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-4&#34;&gt;&lt;a href=&#34;#cb1-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; x  &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; x &lt;span class=&#34;op&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;20&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;と書ける．ただ，この定義はどこか味気ない．&lt;code&gt;isAdult&lt;/code&gt; が受け取るデータは，年齢を表していて，整数か未詳かの状態を持つので，&lt;code&gt;Maybe Int&lt;/code&gt; はデータを正確に捉えられている．しかし，&lt;code&gt;Maybe Int&lt;/code&gt; に適合するデータは他に無数にあるため，&lt;code&gt;isAdult&lt;/code&gt; が受け取るデータが年齢を表すのか知能指数を表すのか，はたまた今までお酒を飲んだことのある回数なのかは推測しないと分からない．年齢を表すデータ型を新たに定義して，それを受け取るようにすればもっとプログラムがクールになるだろう．&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; で新しくデータ型を定義する最も簡単な方法は，&lt;code&gt;type&lt;/code&gt; キーワードを使って型シノニム &lt;span class=&#34;ascii&#34;&gt;(type synonym)&lt;/span&gt; を定義する方法だ．シノニムとは，別名という意味で，型シノニムは文字通り，ある型の別名を表す．今回は次のように使える&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Age&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;isAdult ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Age&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-4&#34;&gt;&lt;a href=&#34;#cb2-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;isAdult age &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt; age &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-5&#34;&gt;&lt;a href=&#34;#cb2-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-6&#34;&gt;&lt;a href=&#34;#cb2-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; x  &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; x &lt;span class=&#34;op&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;20&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これで関数 &lt;code&gt;isAdult&lt;/code&gt; は，先ほどと比べてとても明確になった．&lt;code&gt;Age&lt;/code&gt; は &lt;code&gt;Maybe Int&lt;/code&gt; を元に作られた型シノニムで，つまり &lt;code&gt;Age&lt;/code&gt; は &lt;code&gt;Maybe Int&lt;/code&gt; の別名になっている．単なる別名なので，&lt;code&gt;isAdult&lt;/code&gt; は &lt;code&gt;Maybe Int -&amp;gt; Bool&lt;/code&gt; 型の関数だと思って使うこともできる．&lt;span class=&#34;ascii&#34;&gt;GHCi&lt;/span&gt; で試してみよう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span class=&#34;ot&#34;&gt;isAdult ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Bool&lt;/span&gt;) (&lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Age&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb3-2&#34;&gt;&lt;a href=&#34;#cb3-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Maybe Int&lt;/code&gt; を &lt;code&gt;Age&lt;/code&gt; だと思うこともできるしその逆もできる．型シノニムと元となった型は自在に取り替え可能だ．型シノニムはとても手軽なので，&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; の標準ライブラリでも使われている．例えば，次のようなデータ型が型シノニムで定義されている&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; [&lt;span class=&#34;dt&#34;&gt;Char&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;FilePath&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;文字列は文字のリストと見做せる．そこから文字列によるデータ型 &lt;code&gt;String&lt;/code&gt; は，単に文字のリスト型の型シノニムで定義されている．文字列に対してリストの関数を自由に適用できるのは，このためだ．ファイルのパスによるデータ型 &lt;code&gt;FilePath&lt;/code&gt; は &lt;code&gt;String&lt;/code&gt; の型シノニムで定義されている．なので，文字列の関数を自由に適用できる．&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; の型シノニムは，これだけに止まらずもっと強力な機能も持っている．例えば，型シノニムは型コンストラクタ，すなわち型を受け取って新たな型を作るコンストラクタに対しても作れる&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Option&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この型シノニムを使うと，&lt;code&gt;Maybe Int&lt;/code&gt; と書く代わりに &lt;code&gt;Option Int&lt;/code&gt; と書くことも可能だ．部分適用された型コンストラクタに対する型シノニムも書ける&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Failable&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Either&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この型シノニムを使うと，&lt;code&gt;Either String ()&lt;/code&gt; と書く代わりに &lt;code&gt;Failable ()&lt;/code&gt; と書くことができる．&lt;/p&gt;
&lt;p&gt;さらに型シノニムは，パラメータを持つことができる&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb7&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb7-1&#34;&gt;&lt;a href=&#34;#cb7-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;List&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; [a]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この型シノニムを使うと，&lt;code&gt;[Int]&lt;/code&gt; は &lt;code&gt;List Int&lt;/code&gt; と書ける．ただし，型シノニムはあくまで別名なので，全てのパラメータを適用した状態でしか書けないことに注意する必要がある．例えば，次のプログラムはコンパイルエラーになる&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb8&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb8-1&#34;&gt;&lt;a href=&#34;#cb8-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Apply&lt;/span&gt; f a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&#34;cb8-2&#34;&gt;&lt;a href=&#34;#cb8-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ApplyMaybe&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Apply&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Apply&lt;/code&gt; は&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つのパラメータをとるが，&lt;code&gt;ApplyMaybe&lt;/code&gt; は &lt;code&gt;Apply&lt;/code&gt; に&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つのパラメータしか渡していない．この場合，&lt;code&gt;Apply Maybe&lt;/code&gt; という型がどういう型の別名になるか &lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; は分からないため，この型を拒否する．このプログラムを修正するには，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb9&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb9-1&#34;&gt;&lt;a href=&#34;#cb9-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Apply&lt;/span&gt; f a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&#34;cb9-2&#34;&gt;&lt;a href=&#34;#cb9-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ApplyMaybe&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Apply&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;というように，&lt;code&gt;Apply&lt;/code&gt; に全ての引数を渡してやる必要がある．こうすることで，&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; は &lt;code&gt;Apply&lt;/code&gt; の定義から &lt;code&gt;Apply Maybe a&lt;/code&gt; が &lt;code&gt;Maybe a&lt;/code&gt; の別名であると認識できるようになる &lt;a href=&#34;#fn1&#34; class=&#34;footnote-ref&#34; id=&#34;fnref1&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;．&lt;/p&gt;
&lt;p&gt;型シノニムは，他にも幾つか用途上で制限がある．&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つ目は再帰的な型シノニムが作れないという制限だ．例えば，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb10&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb10-1&#34;&gt;&lt;a href=&#34;#cb10-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;InfiniteList&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (a, &lt;span class=&#34;dt&#34;&gt;InfiniteList&lt;/span&gt; a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;という定義は &lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; では却下される．相互再帰的な定義も許容されていない&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb11&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb11-1&#34;&gt;&lt;a href=&#34;#cb11-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Rec1&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; [&lt;span class=&#34;dt&#34;&gt;Rec2&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&#34;cb11-2&#34;&gt;&lt;a href=&#34;#cb11-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Rec2&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; [&lt;span class=&#34;dt&#34;&gt;Rec1&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Rec1&lt;/code&gt; の型を具体的に求めようとすると，&lt;code&gt;[Rec2]&lt;/code&gt; の型になる．&lt;code&gt;Rec2&lt;/code&gt; はやっぱり型シノニムで，&lt;code&gt;[Rec1]&lt;/code&gt; の別名なので，この型はさらに &lt;code&gt;[[Rec1]]&lt;/code&gt; という型になる．このようにして具体的な型を求めようとしても永遠に型シノニムがどこかしらに入り込むことになってしまい，型シノニムが現れない型を求めることはできない．&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; ではそのようなことがないように，そのような定義を排除している &lt;a href=&#34;#fn2&#34; class=&#34;footnote-ref&#34; id=&#34;fnref2&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;．&lt;/p&gt;
&lt;p&gt;もう&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの制約は，型シノニムを型クラスのインスタンスとして使えないというものだ．例えば，次のようなことはできない&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb12&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb12-1&#34;&gt;&lt;a href=&#34;#cb12-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;I&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-2&#34;&gt;&lt;a href=&#34;#cb12-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-3&#34;&gt;&lt;a href=&#34;#cb12-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;C&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb12-4&#34;&gt;&lt;a href=&#34;#cb12-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;C&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;I&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;代わりに，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb13&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb13-1&#34;&gt;&lt;a href=&#34;#cb13-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;C&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb13-2&#34;&gt;&lt;a href=&#34;#cb13-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;C&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;というように型シノニムを使わず書く必要がある．これは型シノニムを使って書けない唯一の例外だ．ただ，この制限は本質的なものではなく，&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; 標準で型シノニムに対する混乱を避けるための制限になっている．もし，型シノニムに対してインスタンスを書けるようにしても，型シノニムは単なる別名なので，それは元となった型に対してインスタンスを定義してることと同じになる．このため，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb14&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb14-1&#34;&gt;&lt;a href=&#34;#cb14-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;f ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;C&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb14-2&#34;&gt;&lt;a href=&#34;#cb14-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;f x &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;という関数は，&lt;code&gt;type Age = Int&lt;/code&gt; による型シノニム &lt;code&gt;Age&lt;/code&gt; に対して &lt;code&gt;C&lt;/code&gt; のインスタンスが定義されていた場合，&lt;code&gt;a&lt;/code&gt; が &lt;code&gt;Age&lt;/code&gt; の場合も &lt;code&gt;Int&lt;/code&gt; の場合も許容される．これは，プログラマが意図していない動作かもしれない．つまり，年齢のデータだけにインスタンスを定義したつもりが，整数データ全般に対していつのまにかインスタンスを定義してしまったことになるからだ &lt;a href=&#34;#fn3&#34; class=&#34;footnote-ref&#34; id=&#34;fnref3&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;．&lt;/p&gt;
&lt;p&gt;これらの制限はあるものの，型シノニムはデータ型を定義する上でとても強力で，しかも簡単に使用できる機能だ．&lt;/p&gt;
&lt;h2 id=&#34;代数的データ型&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#代数的データ型&#34; title=&#34;代数的データ型&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;代数的データ型&lt;/h2&gt;
&lt;p&gt;さて，型シノニムでデータ型を定義する場合には幾つかの制限があった．では，この制限を超えたデータ型を定義する方法はないのだろうか？ そのような場合には代数的データ型 &lt;span class=&#34;ascii&#34;&gt;(algebraic datatype)&lt;/span&gt; を使うことができる．&lt;/p&gt;
&lt;p&gt;代数的データ型は，複数の型の値を統合して&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの型の値として扱うデータ型の積と，複数の型の表現範囲を合わせて&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの型として扱うデータ型の和を組み合わせることで構成されている．そして，このデータ型の定義は，型シノニムと異なり完全に新しい型を作り出す．実際の例を見てみよう．&lt;/p&gt;
&lt;p&gt;あなたは積木パズルのパーツそれぞれの面積を計算する関数を，書かなければいけない．積木パズルのパーツはそれぞれ，長方形，真円，三角形から構成されている．まずはこのパーツを &lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; のデータ型に落とし込む必要がある．それぞれのパーツにおいて，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;四角形の面積は縦横の長さ&lt;/li&gt;
&lt;li&gt;真円は半径&lt;/li&gt;
&lt;li&gt;三角形は三辺の長さ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;によって特徴付けられている．では，これを代数的データ型に落とし込んでみよう&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb15&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb15-1&#34;&gt;&lt;a href=&#34;#cb15-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PuzzleElement&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-2&#34;&gt;&lt;a href=&#34;#cb15-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Rect&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-3&#34;&gt;&lt;a href=&#34;#cb15-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;dt&#34;&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-4&#34;&gt;&lt;a href=&#34;#cb15-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;co&#34;&gt;-- ^ 縦の長さ&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-5&#34;&gt;&lt;a href=&#34;#cb15-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;dt&#34;&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-6&#34;&gt;&lt;a href=&#34;#cb15-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;co&#34;&gt;-- ^ 横の長さ&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-7&#34;&gt;&lt;a href=&#34;#cb15-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;op&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Circle&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-8&#34;&gt;&lt;a href=&#34;#cb15-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;dt&#34;&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-9&#34;&gt;&lt;a href=&#34;#cb15-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;co&#34;&gt;-- ^ 半径&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-10&#34;&gt;&lt;a href=&#34;#cb15-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;op&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Triangle&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-11&#34;&gt;&lt;a href=&#34;#cb15-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;-- ^ 三つの辺の長さを与える&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb15-12&#34;&gt;&lt;a href=&#34;#cb15-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;dt&#34;&gt;Double&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Double&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Double&lt;/span&gt; &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この定義は，&lt;code&gt;PuzzleElement&lt;/code&gt; という新しい型を作り，&lt;span class=&#34;ascii&#34;&gt;3&lt;/span&gt;つの値コンストラクタを作る．それぞれ&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Rect :: Double -&amp;gt; Double -&amp;gt; PuzzleElement&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Circle :: Double -&amp;gt; PuzzleElement&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Triangle :: Double -&amp;gt; Double -&amp;gt; Double -&amp;gt; PuzzleElement&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という型を持つ．&lt;code&gt;Rect&lt;/code&gt; は &lt;code&gt;Double&lt;/code&gt; 型の値を&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つ受け取り，その&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つの値を &lt;code&gt;PuzzleElement&lt;/code&gt; 型の&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの値として統合する．つまり，&lt;code&gt;Double&lt;/code&gt; 型&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つの積を作る．&lt;code&gt;Circle&lt;/code&gt; や &lt;code&gt;Triangle&lt;/code&gt; も同様だ．そして，&lt;code&gt;PuzzleElement&lt;/code&gt; 型は&lt;span class=&#34;ascii&#34;&gt;3&lt;/span&gt;種類の積の値のいずれかを表し，すなわちこれら&lt;span class=&#34;ascii&#34;&gt;3&lt;/span&gt;種類の積の和を表す．このように，積和によって新しいデータ型を定義できるのが &lt;code&gt;data&lt;/code&gt; 宣言であり，それによって定義されるのが代数的データ型になる．&lt;/p&gt;
&lt;p&gt;代数的データ型の値から統合した値を取り出したい時は，&lt;code&gt;case&lt;/code&gt; 文を使ったパターンマッチを行う&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb16&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb16-1&#34;&gt;&lt;a href=&#34;#cb16-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;areaMeasure ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PuzzleElement&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-2&#34;&gt;&lt;a href=&#34;#cb16-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;areaMeasure x &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt; x &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-3&#34;&gt;&lt;a href=&#34;#cb16-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Rect&lt;/span&gt; w h &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; w &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; h&lt;/span&gt;
&lt;span id=&#34;cb16-4&#34;&gt;&lt;a href=&#34;#cb16-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Circle&lt;/span&gt; r &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; r &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; r &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;pi&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-5&#34;&gt;&lt;a href=&#34;#cb16-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;Triangle&lt;/span&gt; s1 s2 s3 &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-6&#34;&gt;&lt;a href=&#34;#cb16-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; s &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (s1 &lt;span class=&#34;op&#34;&gt;+&lt;/span&gt; s2 &lt;span class=&#34;op&#34;&gt;+&lt;/span&gt; s3) &lt;span class=&#34;op&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb16-7&#34;&gt;&lt;a href=&#34;#cb16-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;kw&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;sqrt&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; s &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; (s &lt;span class=&#34;op&#34;&gt;-&lt;/span&gt; s1) &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; (s &lt;span class=&#34;op&#34;&gt;-&lt;/span&gt; s2) &lt;span class=&#34;op&#34;&gt;*&lt;/span&gt; (s &lt;span class=&#34;op&#34;&gt;-&lt;/span&gt; s3)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;areaMeasure&lt;/code&gt; によってパズルのピースの面積を求めることができるようになった．&lt;/p&gt;
&lt;p&gt;前に紹介した型シノニムは，ある型に対してその別名を与えるだけだった．それに比べ，代数的データ型では新しいデータ型を作り，その型の値を作る値コンストラクタを定義する．そして，型シノニムと大きく異なる点は，型システム上からは新たに定義された型しか分からず，実際にそのデータ型がどういう型から構成されるか分からない点にある．&lt;code&gt;PuzzleElement&lt;/code&gt; 型の値は，もしかしたら &lt;code&gt;Double&lt;/code&gt; 型の&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つの値から &lt;code&gt;Rect&lt;/code&gt; コンストラクタを介して作られているかもしれないし，&lt;code&gt;Double&lt;/code&gt; 型&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの値から &lt;code&gt;Circle&lt;/code&gt; コンストラクタを通して作られているかもしれない．これは実行時にその関数でパターンマッチをしてみて初めて分かることだ．型シノニムでは，型システムからそれがどういう型を元にしていたか分かるが，代数的データ型で観測できるのは新たに作られたデータ型があることだけだ．この違いは，代数的データ型と型シノニムの制約の違いに表れてくる．代数的データ型では，型シノニムの時に挙げたような制約はない．&lt;/p&gt;
&lt;p&gt;例えば，代数的データ型は型シノニムと同様，パラメータをとることができ，さらに部分適用も可能だ &lt;a href=&#34;#fn4&#34; class=&#34;footnote-ref&#34; id=&#34;fnref4&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt;&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb17&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb17-1&#34;&gt;&lt;a href=&#34;#cb17-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Apply&lt;/span&gt; f a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Apply&lt;/span&gt; (f a)&lt;/span&gt;
&lt;span id=&#34;cb17-2&#34;&gt;&lt;a href=&#34;#cb17-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;ApplyMaybe&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Apply&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは &lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; の正しいプログラムになる．&lt;code&gt;Apply&lt;/code&gt; は，&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つのパラメータをとる型コンストラクタになっていて，データ型 &lt;code&gt;Apply f a&lt;/code&gt; の値を作る方法として，&lt;code&gt;f a&lt;/code&gt; 型の値から値コンストラクタ &lt;code&gt;Apply :: f a -&amp;gt; Apply f a&lt;/code&gt; を通す方法がある．&lt;code&gt;ApplyMaybe&lt;/code&gt; は &lt;code&gt;Apply Maybe&lt;/code&gt; の型シノニムになっていて，これを使えば &lt;code&gt;Apply Maybe Int&lt;/code&gt; と書く代わりに &lt;code&gt;ApplyMaybe Int&lt;/code&gt; と書けるようになる．&lt;code&gt;ApplyMaybe&lt;/code&gt; の定義は，&lt;code&gt;Apply&lt;/code&gt; に対して&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つのパラメータしか渡していない．にも関わらず正しいというのが，型シノニムと異なる点になる．&lt;/p&gt;
&lt;p&gt;再帰的なデータ型を代数的データ型で定義することも可能だ&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb18&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb18-1&#34;&gt;&lt;a href=&#34;#cb18-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;List&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb18-2&#34;&gt;&lt;a href=&#34;#cb18-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Cons&lt;/span&gt; a (&lt;span class=&#34;dt&#34;&gt;List&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&#34;cb18-3&#34;&gt;&lt;a href=&#34;#cb18-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;op&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nil&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;データ型 &lt;code&gt;List a&lt;/code&gt; は &lt;code&gt;a&lt;/code&gt; 型の要素を持つ単連結リストを表す．値コンストラクタが &lt;code&gt;List a&lt;/code&gt; 型の値を受け取ることがポイントだ．型シノニムでは，その型の定義に自身を含めることはできなかった．これは実際の具体的な型を求めようとした時，その計算が永遠に終わらなくなってしまうからだった．代数的データ型 &lt;code&gt;List a&lt;/code&gt; ではその型は単に新しい型として作られ，実際にその型の値がどういう型の値によって構成されているか知る必要はない．&lt;code&gt;List a&lt;/code&gt; はそれ自体が具体的な型であり &lt;a href=&#34;#fn5&#34; class=&#34;footnote-ref&#34; id=&#34;fnref5&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt; ，それ以上計算する必要はないからだ．代数的データ型において，定義された型とその型の値を作る方法は分離されている．そのため，データ型の計算においてその型の値を作る方法は考慮されない．よって，自身が定義中で用いられても，型シノニムのようにデータ型の計算が永遠に終わることがないということはないため，その操作が許容されている．&lt;/p&gt;
&lt;p&gt;もちろん，新しい型が定義されるため，型クラスのインスタンスを混乱なく定義できる．代数的データ型を作成した時，基本的なインスタンスを定義することは &lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; プログラミングにおいてよくあることだ．&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; では，言語機能としてそれを支援する機能がある．それは，&lt;code&gt;deriving&lt;/code&gt; 構文というもので，&lt;code&gt;Eq&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;Ord&lt;/code&gt; などの標準的な型クラスを，データ型の定義から自動で導出してくれる．例えば，&lt;code&gt;List a&lt;/code&gt; に対して使ってみると，以下のようになる&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb19&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb19-1&#34;&gt;&lt;a href=&#34;#cb19-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;List&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb19-2&#34;&gt;&lt;a href=&#34;#cb19-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Cons&lt;/span&gt; a (&lt;span class=&#34;dt&#34;&gt;List&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&#34;cb19-3&#34;&gt;&lt;a href=&#34;#cb19-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;op&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nil&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb19-4&#34;&gt;&lt;a href=&#34;#cb19-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;kw&#34;&gt;deriving&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Eq&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;Ord&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;Show&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このように代数的データ型は，型シノニムでは定義できなかったデータ型を定義することができる．そして，代数的データ型は全く新しい型を作ることもできる&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb20&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb20-1&#34;&gt;&lt;a href=&#34;#cb20-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nat&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-2&#34;&gt;&lt;a href=&#34;#cb20-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Succ&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nat&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb20-3&#34;&gt;&lt;a href=&#34;#cb20-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;op&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Zero&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このデータ型 &lt;code&gt;Nat&lt;/code&gt; は，他の型には依存しない全く新しい型だ．このように，代数的データ型は型シノニムと異なり全く新しい構造を作り出すことができる．&lt;/p&gt;
&lt;p&gt;ただ，その代わり既存の関数を流用できなくなってしまう場合がある．例えば，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb21&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb21-1&#34;&gt;&lt;a href=&#34;#cb21-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; a b &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; a b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;は，&lt;code&gt;(a, b)&lt;/code&gt; と構造が同じであり，&lt;code&gt;(a, b)&lt;/code&gt; に対する関数 &lt;code&gt;fst :: (a, b) -&amp;gt; a&lt;/code&gt; を適用できてもいいはずだ．ところが，データ型 &lt;code&gt;Tuple a b&lt;/code&gt; とその値コンストラクタは型システム上は切り離されているため，自身の値が &lt;code&gt;(a, b)&lt;/code&gt; の値と同じ方法でしか構成できないことを知らない．&lt;code&gt;Tuple a b&lt;/code&gt; と &lt;code&gt;(a, b)&lt;/code&gt; において型上で言及できることは，それらが異なる型であるということだけだ．なので，&lt;code&gt;fst&lt;/code&gt; に &lt;code&gt;Tuple a b&lt;/code&gt; 型の値を渡すことはできない．これは，もし型シノニムを使って，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb22&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb22-1&#34;&gt;&lt;a href=&#34;#cb22-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; a b &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; (a, b)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;と定義した場合は解決する問題だ &lt;a href=&#34;#fn6&#34; class=&#34;footnote-ref&#34; id=&#34;fnref6&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/a&gt;．&lt;/p&gt;
&lt;p&gt;このように両者にはトレードオフがあり，利用目的に合った使い分けをするのがいいだろう．&lt;/p&gt;
&lt;p&gt;さて，&lt;code&gt;data&lt;/code&gt; 宣言の構文は他に&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つ，便利な機能がある．&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つは正格性フラグと呼ばれる機能で，値コンストラクタにおいて引数を正格に評価することを強制できる．例えば，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb23&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb23-1&#34;&gt;&lt;a href=&#34;#cb23-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;StrictTuple&lt;/span&gt; a b &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;StrictTuple&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;!&lt;/span&gt;a &lt;span class=&#34;op&#34;&gt;!&lt;/span&gt;b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;というように，正格性フラグ &lt;code&gt;!&lt;/code&gt; を使った定義を行うと，値コンストラクタ &lt;code&gt;StrictTuple :: a -&amp;gt; b -&amp;gt; StrictTuple&lt;/code&gt; はその引数を正格に評価してから格納するようになる．通常，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb24&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb24-1&#34;&gt;&lt;a href=&#34;#cb24-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; a b &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; a b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のように正格性フラグを使わない定義では，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb25&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb25-1&#34;&gt;&lt;a href=&#34;#cb25-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;undefined&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;undefined&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; _ _ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb25-2&#34;&gt;&lt;a href=&#34;#cb25-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のように値コンストラクタは受け取った引数の評価を行わず，素直にそのままの形で遅延させて格納するため，エラーを出す式を渡してもその式の評価を行わない限りエラーにはならない．これは通常の関数の動作と同じになる．ところが，正格性フラグを使用した &lt;code&gt;StrictTuple&lt;/code&gt; の場合，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb26&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb26-1&#34;&gt;&lt;a href=&#34;#cb26-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;StrictTuple&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;undefined&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;undefined&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;StrictTuple&lt;/span&gt; _ _ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb26-2&#34;&gt;&lt;a href=&#34;#cb26-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;***&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Exception&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; Prelude.undefined&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のように引数の評価を行うため，エラーを出す式を受け取った場合値コンストラクタの適用においてその式を評価しエラーを出す．データ型を作成する際，その元となる式の評価を強制させることはパフォーマンスに大きく寄与する．そのため，そのようなことを支援するために正格性フラグは設けられている．&lt;/p&gt;
&lt;p&gt;また，代数的データ型の値コンストラクタはフィールド名を持つことができる&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb27&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb27-1&#34;&gt;&lt;a href=&#34;#cb27-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; a b &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb27-2&#34;&gt;&lt;a href=&#34;#cb27-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  {&lt;span class=&#34;ot&#34;&gt; firstVal  ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb27-3&#34;&gt;&lt;a href=&#34;#cb27-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  ,&lt;span class=&#34;ot&#34;&gt; secondVal ::&lt;/span&gt; b&lt;/span&gt;
&lt;span id=&#34;cb27-4&#34;&gt;&lt;a href=&#34;#cb27-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この場合，型コンストラクタ &lt;code&gt;Tuple&lt;/code&gt;，値コンストラクタ &lt;code&gt;Tuple :: a -&amp;gt; b -&amp;gt; Tuple a b&lt;/code&gt; の他に，関数 &lt;code&gt;firstVal :: Tuple a b -&amp;gt; a&lt;/code&gt;， &lt;code&gt;secondVal :: Tuple a b -&amp;gt; b&lt;/code&gt; が作られる．また，値コンストラクタの呼び出しにおいて特別なレコード構文 &lt;code&gt;Tuple { firstVal = 0, secondVal = 1 }&lt;/code&gt; を使用でき，またレコード更新構文 &lt;code&gt;(Tuple 2 1) { firstVal = 0 }&lt;/code&gt; を使用できる．これらは両者 &lt;code&gt;Tuple 0 1&lt;/code&gt; と同様の値が作成される．&lt;/p&gt;
&lt;h2 id=&#34;ある型を元に新たな型を作る-datatype-renaming&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#ある型を元に新たな型を作る-datatype-renaming&#34; title=&#34;ある型を元に新たな型を作る-datatype-renaming&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;ある型を元に新たな型を作る &lt;span class=&#34;ascii&#34;&gt;(Datatype Renaming)&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;さて，これまで見てきたように，型シノニムは型の別名を定義し，代数的データ型は型の積和により新たなデータ型を定義するものだった．&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; にはもう&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つデータ型を定義する方法がある．それが &lt;code&gt;newtype&lt;/code&gt; 宣言だ．この宣言によって作られるデータ型は，型システム上は代数的データ型と同じように扱われ，実行時は型シノニムと同様の動作をする．&lt;/p&gt;
&lt;p&gt;&lt;code&gt;newtype&lt;/code&gt; 宣言の構文は，&lt;code&gt;data&lt;/code&gt; 宣言と同じような形をしている&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb28&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb28-1&#34;&gt;&lt;a href=&#34;#cb28-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;フィールド名をつけることもできる&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb29&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb29-1&#34;&gt;&lt;a href=&#34;#cb29-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb29-2&#34;&gt;&lt;a href=&#34;#cb29-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  {&lt;span class=&#34;ot&#34;&gt; unIdentity ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb29-3&#34;&gt;&lt;a href=&#34;#cb29-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;この場合 &lt;code&gt;data&lt;/code&gt; 宣言と同様に，型コンストラクタ &lt;code&gt;Identity&lt;/code&gt;，値コンストラクタ &lt;code&gt;Identity&lt;/code&gt; が作られることになる．ただし，&lt;code&gt;data&lt;/code&gt; 宣言と異なり &lt;code&gt;newtype&lt;/code&gt; は積和の機能を使用することはできない．単にある&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの型を受け取る値コンストラクタしか定義できない．なので，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb30&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb30-1&#34;&gt;&lt;a href=&#34;#cb30-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Unit&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Unit&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb30-2&#34;&gt;&lt;a href=&#34;#cb30-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; a b &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Tuple&lt;/span&gt; a b&lt;/span&gt;
&lt;span id=&#34;cb30-3&#34;&gt;&lt;a href=&#34;#cb30-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Enum&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;A&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;B&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;C&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;はいずれも受け入れられない．この &lt;code&gt;newtype&lt;/code&gt; の制約はいまいちよく分からない．では，このような制約によりどのような違いが出るのだろうか？ &lt;code&gt;newtype&lt;/code&gt; と &lt;code&gt;data&lt;/code&gt; は型システム上は違いはない．しかし，パターンマッチの動作など，実行時の動作に少し差異が設けられている．例えば，通常&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb31&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb31-1&#34;&gt;&lt;a href=&#34;#cb31-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;DataIdentity&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;DataIdentity&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;において，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb32&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb32-1&#34;&gt;&lt;a href=&#34;#cb32-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; undefined ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;DataIdentity&lt;/span&gt; () &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;DataIdentity&lt;/span&gt; _ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb32-2&#34;&gt;&lt;a href=&#34;#cb32-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;***&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Exception&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt; Prelude.undefined&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のようにエラーを出す式をパターンマッチで分解しようとするとエラーが出力される．ところが，&lt;code&gt;newtype&lt;/code&gt; によって作られた値コンストラクタの場合，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb33&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb33-1&#34;&gt;&lt;a href=&#34;#cb33-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; undefined ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; () &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; _ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb33-2&#34;&gt;&lt;a href=&#34;#cb33-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のようにパターンマッチ時にエラーが出されることはない．&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; では &lt;code&gt;newtype&lt;/code&gt; で作られた値コンストラクタが実行動作に影響することはないと規定されている．よって，上のパターンマッチは，以下と同様の動きをすることになっている&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb34&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb34-1&#34;&gt;&lt;a href=&#34;#cb34-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; undefined ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; () &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt; _ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb34-2&#34;&gt;&lt;a href=&#34;#cb34-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このように値コンストラクタを指定しないパターンマッチの場合，&lt;code&gt;data&lt;/code&gt; 宣言で作られたものもエラーを出さない&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb35&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb35-1&#34;&gt;&lt;a href=&#34;#cb35-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; undefined ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;DataIdentity&lt;/span&gt; () &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt; _ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb35-2&#34;&gt;&lt;a href=&#34;#cb35-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;よって，&lt;code&gt;data&lt;/code&gt; と &lt;code&gt;newtype&lt;/code&gt; で作られた値コンストラクタの動作が異なるのは，パターンマッチにおいて値コンストラクタを指定した場合だけということになる．&lt;/p&gt;
&lt;p&gt;では，&lt;code&gt;newtype&lt;/code&gt; はなぜ値コンストラクタを無視するよう規定されているのだろう？ これは，&lt;code&gt;newtype&lt;/code&gt; によるデータ型が実行時の動作として型シノニムと同様の動作をすることを目的としてしているからだ．値コンストラクタが無視されるのは，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb36&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb36-1&#34;&gt;&lt;a href=&#34;#cb36-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;という宣言は，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb37&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb37-1&#34;&gt;&lt;a href=&#34;#cb37-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IdentitySynonym&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;という宣言と同様の意味を持って欲しいことを &lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; の設計者が意図しているからだ．よって，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb38&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb38-1&#34;&gt;&lt;a href=&#34;#cb38-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; undefined ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; () &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Identity&lt;/span&gt; _ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb38-2&#34;&gt;&lt;a href=&#34;#cb38-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&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=&#34;sourceCode&#34; id=&#34;cb39&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb39-1&#34;&gt;&lt;a href=&#34;#cb39-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; undefined ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IdentitySynonym&lt;/span&gt; () &lt;span class=&#34;kw&#34;&gt;of&lt;/span&gt; _ &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&#34;cb39-2&#34;&gt;&lt;a href=&#34;#cb39-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のように，代数的データ型ではなく型シノニムに合わせてあるため，&lt;code&gt;data&lt;/code&gt; 宣言主体に見ると一見不思議な動作をしていたというわけだ．&lt;/p&gt;
&lt;p&gt;さて，ではなぜわざわざ型シノニムとは別に &lt;code&gt;newtype&lt;/code&gt; 宣言を導入したのだろうか？ 型シノニムには幾つか制約があったのを思い出して欲しい．そして，それらの制約は代数的データ型では解決されたのだった．それは &lt;code&gt;type&lt;/code&gt; 宣言が単に型の別名を導入するのに対し，&lt;code&gt;data&lt;/code&gt; 宣言が完全に新たな型を作るからだった．&lt;code&gt;newtype&lt;/code&gt; はその点に着目し，実行時には単なる別名として動作するが型システム上は完全に別の新たな型を導入することで，&lt;code&gt;type&lt;/code&gt; 宣言同様ある型の別名を作りたいものの型シノニムの制約は回避したい需要を満たすようにしたものだ．&lt;/p&gt;
&lt;p&gt;例えば，大文字小文字を区別しない文字列データを考えてみよう．この場合，&lt;code&gt;&#34;aBc&#34; == &#34;Abc&#34;&lt;/code&gt; であって欲しいが，これは型シノニムで&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb40&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb40-1&#34;&gt;&lt;a href=&#34;#cb40-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsensString&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;と定義するだけでは，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb41&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb41-1&#34;&gt;&lt;a href=&#34;#cb41-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span class=&#34;st&#34;&gt;&amp;quot;aBc&amp;quot;&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsensString&lt;/span&gt;) &lt;span class=&#34;op&#34;&gt;==&lt;/span&gt; (&lt;span class=&#34;st&#34;&gt;&amp;quot;Abc&amp;quot;&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsensString&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb41-2&#34;&gt;&lt;a href=&#34;#cb41-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のままだ．そこで，&lt;code&gt;newtype&lt;/code&gt; を使って，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb42&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb42-1&#34;&gt;&lt;a href=&#34;#cb42-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Char&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Char&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-2&#34;&gt;&lt;a href=&#34;#cb42-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-3&#34;&gt;&lt;a href=&#34;#cb42-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsensString&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsens&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-4&#34;&gt;&lt;a href=&#34;#cb42-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-5&#34;&gt;&lt;a href=&#34;#cb42-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Eq&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsensString&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-6&#34;&gt;&lt;a href=&#34;#cb42-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;dt&#34;&gt;CaseInsens&lt;/span&gt; s1 &lt;span class=&#34;op&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsens&lt;/span&gt; s2 &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; go s1 s2&lt;/span&gt;
&lt;span id=&#34;cb42-7&#34;&gt;&lt;a href=&#34;#cb42-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-8&#34;&gt;&lt;a href=&#34;#cb42-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      go []       []       &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-9&#34;&gt;&lt;a href=&#34;#cb42-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      go []       (_&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;_)    &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-10&#34;&gt;&lt;a href=&#34;#cb42-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      go (_&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;_)    []       &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb42-11&#34;&gt;&lt;a href=&#34;#cb42-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      go (c1&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;cs1) (c2&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;cs2) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Char&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;toLower&lt;/span&gt; c1 &lt;span class=&#34;op&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Char&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;toLower&lt;/span&gt; c2 &lt;span class=&#34;op&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; go cs1 cs2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;とすれば，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb43&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb43-1&#34;&gt;&lt;a href=&#34;#cb43-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsens&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;aBc&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsens&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Abc&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb43-2&#34;&gt;&lt;a href=&#34;#cb43-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;とできる．型シノニムは単なる &lt;code&gt;String&lt;/code&gt; の別名なので，&lt;code&gt;String&lt;/code&gt; と異なるインスタンスを新しく定義することはできない．それに対して，&lt;code&gt;newtype&lt;/code&gt; によるデータ型は代数的データ型と同様に自由に定義することができる．そして，値コンストラクタ &lt;code&gt;CaseInsens&lt;/code&gt; は単なる飾りであり，実行時には完全に無視されるため，&lt;code&gt;CaseInsensString&lt;/code&gt; は動作としては &lt;code&gt;String&lt;/code&gt; の別名としてみることができる．&lt;/p&gt;
&lt;p&gt;&lt;code&gt;newtype&lt;/code&gt; は型シノニムでの制約であった，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;再帰的なデータ型が定義できない&lt;/li&gt;
&lt;li&gt;型コンストラクタに対する部分適用ができない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;といった問題も解決する．このように &lt;code&gt;newtype&lt;/code&gt; は型シノニムの問題を改善したデータ型を定義するが，&lt;code&gt;data&lt;/code&gt; 宣言と同様型シノニムでは起きなかった問題も一緒に顕在化させてしまう．&lt;/p&gt;
&lt;p&gt;上の例で，&lt;code&gt;CaseInsens&lt;/code&gt; は飾りだと言ったが，実際にはこの値コンストラクタは必要不可欠であり，重要な役割を持っている．例えば，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb44&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb44-1&#34;&gt;&lt;a href=&#34;#cb44-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsens&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;aBc&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsens&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Abc&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb44-2&#34;&gt;&lt;a href=&#34;#cb44-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;の例は，片方だけ&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb45&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb45-1&#34;&gt;&lt;a href=&#34;#cb45-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;aBc&amp;quot;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CaseInsens&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Abc&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;としてしまうと，コンパイルエラーになってしまう．なぜなら，&lt;code&gt;(==)&lt;/code&gt; は&lt;span class=&#34;ascii&#34;&gt;2&lt;/span&gt;つの引数が同じ型の値である必要があり，&lt;code&gt;&#34;aBc&#34;&lt;/code&gt; の型である &lt;code&gt;String&lt;/code&gt; と &lt;code&gt;CaseInsens &#34;Abc&lt;/code&gt; の型である &lt;code&gt;CaseInsensString&lt;/code&gt; は全く異なる型であるからだ．つまり，値コンストラクタ &lt;code&gt;CaseInsens&lt;/code&gt; は，実行時には何の影響も与えないが，型システム上は全く異なる型の値であることを示すマーカーとなる．そして，型シノニムではデータ型は単なる別名であったが，&lt;code&gt;newtype&lt;/code&gt; は &lt;code&gt;data&lt;/code&gt; と同様全く新たな型として導入する道を選んだため，元の型として受け入れてもらうことが出来なくなってしまったのだ．&lt;/p&gt;
&lt;p&gt;といっても，これは一長一短である．&lt;code&gt;data&lt;/code&gt; と同様 &lt;code&gt;newtype&lt;/code&gt; で作られた型は，型シノニムのように既存の関数を使い回すことができない．その反面，データの意味に沿わないプログラムを型によって弾くことができるという点は長所になる場合もある．例えば，&lt;code&gt;&#34;aBc&#34; == CaseInsens &#34;Abc&#34;&lt;/code&gt; の例は，一体どのような結果を返すべきか一見して分からない．両者は単なる文字列と，大文字小文字を区別しない文字列という異なるデータを表しており，その比較は定義されないとするのが自然だろう．このような場合に，型シノニムでは定義されないことを表す方法はなかったが，&lt;code&gt;newtype&lt;/code&gt; は元の型と異なる型を持つので，そのような仕組みを作ることができる．&lt;/p&gt;
&lt;p&gt;さて，&lt;code&gt;newtype&lt;/code&gt; において値コンストラクタは実行時に何の影響も及ぼさないことと，何故そうなっているかについて分かってもらえただろうか？ この影響は，パターンマッチ以外にも表れる．例えば，&lt;code&gt;newtype&lt;/code&gt; の値コンストラクタに正格性フラグの機能はない．&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb46&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb46-1&#34;&gt;&lt;a href=&#34;#cb46-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;StrictNewtype&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;StrictNewtype&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;というプログラムは，&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; では受け入れられない．なぜなら，これを受け入れた場合，値コンストラクタがあるかどうかによって実行時の動作が変わってしまうからだ．ただ，その他の &lt;code&gt;data&lt;/code&gt; 宣言の機能は使用できる．&lt;code&gt;deriving&lt;/code&gt; も使用できる．&lt;code&gt;newtype&lt;/code&gt; で作られたデータ型は，元のデータ型のインスタンスを継承することはできない．全く新たな型を作ったため，更地の状態から始まる．ただし，&lt;code&gt;deriving&lt;/code&gt; を使うことでインスタンスを用意に導出することは可能だ．ただ，標準クラスのインスタンスしか自動で導出できないため，自身で定義した型クラスなどのインスタンスは一から書く必要がある．そのことには，注意する必要があるだろう &lt;a href=&#34;#fn7&#34; class=&#34;footnote-ref&#34; id=&#34;fnref7&#34; role=&#34;doc-noteref&#34;&gt;&lt;sup&gt;7&lt;/sup&gt;&lt;/a&gt;．&lt;/p&gt;
&lt;p&gt;最後に少し応用的な &lt;code&gt;newtype&lt;/code&gt; の使い方を紹介しよう．&lt;code&gt;newtype&lt;/code&gt; は上のように目的に合わせて型を既存の型から作る他，型シノニムの制約によって定義できない型上の計算を実現するのにも使用できる．例えば，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb47&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb47-1&#34;&gt;&lt;a href=&#34;#cb47-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Fix&lt;/span&gt; f &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Fix&lt;/span&gt; (f (&lt;span class=&#34;dt&#34;&gt;Fix&lt;/span&gt; f))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;という変わったデータ型を使うと，型上の不動点演算をエミュレートできる．また，&lt;code&gt;newtype&lt;/code&gt; を使うことで幽霊型による曖昧な型を避けることもできる．例えば，&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb48&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb48-1&#34;&gt;&lt;a href=&#34;#cb48-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WithAnn&lt;/span&gt; ann a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb48-2&#34;&gt;&lt;a href=&#34;#cb48-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb48-3&#34;&gt;&lt;a href=&#34;#cb48-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;readShow ::&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Read&lt;/span&gt; a, &lt;span class=&#34;dt&#34;&gt;Show&lt;/span&gt; a) &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WithAnn&lt;/span&gt; a &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb48-4&#34;&gt;&lt;a href=&#34;#cb48-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;readShow s &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;read&lt;/span&gt; s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;を考える．この関数 &lt;code&gt;readShow&lt;/code&gt; は，&lt;code&gt;WithAnn&lt;/code&gt; で引数に &lt;code&gt;a&lt;/code&gt; を使っているにもかかわらず &lt;code&gt;a&lt;/code&gt; が曖昧な型になるため弾かれる．なぜなら，型シノニム &lt;code&gt;WithAnn a String&lt;/code&gt; は &lt;code&gt;String&lt;/code&gt; と書いてるのと同じであり，&lt;code&gt;readShow&lt;/code&gt; は&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb49&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb49-1&#34;&gt;&lt;a href=&#34;#cb49-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;readShow ::&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Read&lt;/span&gt; a, &lt;span class=&#34;dt&#34;&gt;Show&lt;/span&gt; a) &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;という型を持つのと同様になってしまうからだ．このため，制約だけに &lt;code&gt;a&lt;/code&gt; が現れることになってしまい，曖昧な型になってしまう．この例のような，型シノニムが具体化されてしまうことで曖昧な型が生じる問題は，&lt;code&gt;newtype&lt;/code&gt; を使用することで回避できる&lt;span class=&#34;ascii&#34;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb50&#34;&gt;&lt;pre class=&#34;sourceCode haskell&#34;&gt;&lt;code class=&#34;sourceCode haskell&#34;&gt;&lt;span id=&#34;cb50-1&#34;&gt;&lt;a href=&#34;#cb50-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;newtype&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WithAnn&lt;/span&gt; ann a &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WithAnn&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&#34;cb50-2&#34;&gt;&lt;a href=&#34;#cb50-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb50-3&#34;&gt;&lt;a href=&#34;#cb50-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ot&#34;&gt;readShow ::&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Read&lt;/span&gt; a, &lt;span class=&#34;dt&#34;&gt;Show&lt;/span&gt; a) &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;WithAnn&lt;/span&gt; a &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb50-4&#34;&gt;&lt;a href=&#34;#cb50-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;readShow (&lt;span class=&#34;dt&#34;&gt;WithAnn&lt;/span&gt; s) &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;show&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;read&lt;/span&gt; s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; は型システム上は &lt;code&gt;WithAnn a String&lt;/code&gt; が実行時に単なる &lt;code&gt;String&lt;/code&gt; の別名として扱われることを知らず，これを&lt;span class=&#34;ascii&#34;&gt;1&lt;/span&gt;つの具体化された型として認識する．このため，実際には &lt;code&gt;a&lt;/code&gt; が引数の値に何ら関与しない場合も，型 &lt;code&gt;a&lt;/code&gt; を伴う型として残る．よって，この場合は &lt;code&gt;a&lt;/code&gt; は曖昧な型にならず，&lt;code&gt;WithAnn a String&lt;/code&gt; の &lt;code&gt;a&lt;/code&gt; の部分にあてがわれる型から特定することができる．このように，型シノニムで早期に元となった型に具体化されることで生じる問題は，&lt;code&gt;newtype&lt;/code&gt; を使うことで実際に値を作る箇所とパターンマッチの箇所での型計算に遅延させることができ，回避できる場合がある．&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;&lt;span class=&#34;link-to-here-outer&#34;&gt;&lt;a href=&#34;#まとめ&#34; title=&#34;まとめ&#34;&gt;&lt;span class=&#34;link-to-here&#34;&gt;Link to&lt;br /&gt;
here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;まとめ&lt;/h2&gt;
&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; の&lt;span class=&#34;ascii&#34;&gt;3&lt;/span&gt;つのデータ型定義方法について紹介した．&lt;/p&gt;
&lt;p&gt;型シノニムは，ある型に対してその別名を与えることで，データ型を定義するものだった．簡易で元の型に対する関数をそのまま流用でき，使いやすい反面，部分適用ができない，再帰的データ型が定義できない，型クラスのインスタンスにできないと言う制約があった．&lt;/p&gt;
&lt;p&gt;代数的データ型は複数の型の積和によって全く新しいデータ型を定義するものだった．型シノニムであった制約を回避でき，新たな構造を導入できるが，関数の流用が困難な場合があり型シノニムとの使い分けが必要だった．&lt;/p&gt;
&lt;p&gt;&lt;code&gt;newtype&lt;/code&gt; によるデータ型は，型システム上は代数的データ型と，実行時の動作は型シノニムと同様といった，それぞれの中間をとったようなものだった．型シノニムのような関数の流用ができない場合はあるものの，その代わり型シノニムの制約を回避でき，型システム上は全く異なる振る舞いを行うことも可能だった．&lt;/p&gt;
&lt;p&gt;これらは，それぞれが一長一短を持ち，目的にあった使い分けをする必要がある．この記事が，そのような場合の助けになればいいと思う．では，今回はこれで．&lt;/p&gt;
&lt;section id=&#34;footnotes&#34; class=&#34;footnotes footnotes-end-of-document&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn1&#34;&gt;&lt;p&gt;型シノニムに対して部分適用を許容する一般的な方法は，型上にもラムダ抽象にあたる表現を導入することである．ただ，この場合型上の演算が停止しない場合があり，型システムが決定不能になる．このため，&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; では型シノニムに対しての部分適用は許容していない．&lt;a href=&#34;#fnref1&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn2&#34;&gt;&lt;p&gt;等価再帰データ型 &lt;span class=&#34;ascii&#34;&gt;(equirecursive types)&lt;/span&gt; と呼ばれる特別な型を型システムに導入することで，このような型を許容する理論は存在するが，この理論はとても複雑で型検査のアルゴリズムも難しくなりがちである．&lt;a href=&#34;#fnref2&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn3&#34;&gt;&lt;p&gt;ただ，このような混乱が起こるかもしれないことを許容し，利便性のため型シノニムをインスタンス定義で使いたい場合，&lt;code&gt;TypeSynonymInstances&lt;/code&gt; という &lt;span class=&#34;ascii&#34;&gt;GHC&lt;/span&gt; 拡張を有効にすることで許容されるようになる．&lt;a href=&#34;#fnref3&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn4&#34;&gt;&lt;p&gt;型上の計算によって，実際の型が特定される型シノニムとは異なり，代数的データ型の型コンストラクタはそれ自体がもう計算できないものになる．それは部分適用されても同様であり，部分適用を許容することで型シノニムと同様の問題は起こらない．これが，代数的データ型で部分適用が許容されている理由になる．&lt;a href=&#34;#fnref4&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn5&#34;&gt;&lt;p&gt;実際にはパラメータ &lt;code&gt;a&lt;/code&gt; の部分に具体的な型を当てはめないといけないが，当てはめればそれは完全に具体的な型になる．&lt;a href=&#34;#fnref5&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn6&#34;&gt;&lt;p&gt;なお，代数的データ型でも型シノニムと同様の利点を手に入れるための研究は，&lt;span class=&#34;ascii&#34;&gt;Haskell&lt;/span&gt; では盛んに行われている．例えば，&lt;code&gt;Generic&lt;/code&gt; &lt;span class=&#34;ascii&#34;&gt;/&lt;/span&gt; &lt;code&gt;Data&lt;/code&gt; 型クラス，&lt;code&gt;lens&lt;/code&gt; パッケージなどを使うことで，構造が同じだが異なるデータ型で関数が流用できない問題を回避できる場合がある．&lt;a href=&#34;#fnref6&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&#34;fn7&#34;&gt;&lt;p&gt;&lt;span class=&#34;ascii&#34;&gt;GHC&lt;/span&gt; 拡張では，&lt;code&gt;deriving&lt;/code&gt; 構文の拡張として強力な機能がいくつか搭載されている．特に &lt;code&gt;newtype&lt;/code&gt; によるデータ型の場合は，&lt;code&gt;GeneralizedNewtypeDeriving&lt;/code&gt; や &lt;code&gt;DerivingVia&lt;/code&gt; 拡張を使えば，インスタンスの自動導出の範囲を大幅に拡大できる．&lt;a href=&#34;#fnref7&#34; class=&#34;footnote-back&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&#34;post-navigation&#34; class=&#34;row&#34; style=&#34;margin-top: 20px;&#34;&gt;
            &lt;div class=&#34;col-lg-offset-2 col-lg-3 col-md-offset-1 col-md-4 col-xs-4&#34;&gt;
                
                &lt;i class=&#34;glyphicon glyphicon-chevron-left&#34; aria-hidden=&#34;true&#34; style=&#34;margin-right: 5px;&#34;&gt;&lt;/i&gt;
                &lt;a href=&#34;/posts/2020/antenna-with-gh-actions.html&#34; lang=&#34;ja&#34;&gt;Haskell AntennaのCI/CDをGitHub Actionsに移行する&lt;/a&gt;
                
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-2 col-md-2 col-xs-4 text-center&#34;&gt;
                &lt;a href=&#34;/&#34; lang=&#34;ja&#34;&gt;トップに戻る&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&#34;col-lg-3 col-md-4 col-xs-4&#34;&gt;
                
                &lt;a href=&#34;/posts/2020/strict-gotchas.html&#34; style=&#34;margin-left: auto;&#34; lang=&#34;ja&#34;&gt;Strict拡張を使用する際の注意点&lt;/a&gt;
                &lt;i class=&#34;glyphicon glyphicon-chevron-right&#34; aria-hidden=&#34;true&#34; style=&#34;margin-left: 5px;&#34;&gt;&lt;/i&gt;
                
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/article&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://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 &amp;lt;abc@test.org&amp;gt;
  主鍵フィンガープリント: &amp;lt;snip&amp;gt;
  副鍵フィンガープリント: &amp;lt;snip&amp;gt;

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

それでもこの鍵を使いますか? (y</summary></entry><entry><id>https://syocy.hatenablog.com/entry/2020/04/29/170208</id><title type="text">家から出ない生活４週間</title><updated>2020-04-29T17:02:08+09:00</updated><author><name>syocy</name></author><link href="https://syocy.hatenablog.com/entry/2020/04/29/170208"/><summary type="html">出社非推奨になったのを機に家から出ない生活を始めて４週間が経った。今までやったことをまとめていく。 食料品 せっかくだから生活で縛りプレイをしてみようと思って Amazon と Yodobashi を禁止にしている。この２社は最近評判が良くないこともあるし。 業務スーパーの通販 いわゆるネットスーパーはサイトが激重になっていたり配達可能日がすべて☓になっていたりで機能不全を起こしているようだった。そこで飲食店がメインターゲットであろう業務スーパーなら今空いているだろうという読み。ここではピザ材料、冷凍野菜、割り箸などを入手している。 とにかく業務スーパーの通販を最大限利用するには冷凍室の容積が…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2020/01/01/083723</id><title type="text">2019 年のスライド一挙公開、あるいは 2020 年の方針</title><updated>2020-01-01T08:37:23+09:00</updated><author><name>y_taka_23</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://fumieval.hatenablog.com/entry/2019/12/25/224329</id><title type="text">barbies-thで気軽にHKDを堪能しよう [Haskell AdC 14]</title><updated>2019-12-25T22:43:29+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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://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>y_taka_23</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://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>https://fumieval.hatenablog.com/entry/2019/12/05/191010</id><title type="text">最強にして最速のビルダー、mason</title><updated>2019-12-05T19:10:10+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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>y_taka_23</name></author><link href="https://ccvanishing.hateblo.jp/entry/2019/11/30/215950"/><summary type="html">はじめに マルチスレッドで動作するプログラムの設計は難しい問題です。個々のスレッドの動作は単純に見えても、複数が並行して動作する場合の動作は組み合わせ論的に複雑になります。また、タイミングに依存する不具合は狙って再現することが難しく、通常の単体テストによる検出にも限界があります。 そんなとき、有効な手法がモデル検査です。システムの取りうる状態をあらかじめ網羅的に探索することで、「実際に動作させた際にごく低い確率で踏むバグ」であっても、動作させることなく設計段階で発見することが可能になります。 ところでちょうど先日、デッドロック発見器を自作するハンズオンに参加する機会がありました。内容は非常にシ…</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-21T23:37:54+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/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>2019-11-20T22:22:37+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://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-10-23T20:32:39+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://syocy.hatenablog.com/entry/init-ghc-8-8-1</id><title type="text">HaskellやっていくGHC8.8.1令和元年白露の候</title><updated>2019-09-14T23:40:48+09:00</updated><author><name>syocy</name></author><link href="https://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://fumieval.hatenablog.com/entry/2019/09/07/115437</id><title type="text">単純で頑強なメッセージングシステム、franz</title><updated>2019-09-07T11:54:37+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2019/09/07/115437"/><summary type="html">Haskell製の新しいメッセージングシステムfranz(フランツ)の紹介。 github.com 背景 取引所にあるマシンで取引プログラムを実行するのが我々の仕事だが、朝8時に起動したらあとは昼寝したり酒を飲んだりというわけにはいかない。モニタリングしたり、分析のためにデータを残しておく必要がある。そのため、プログラムによって解析しやすい形でログを出力する。 今までは複数の種類のレコードをシリアライズし、一つのファイルに連結させる独自のフォーマットを10年近く使っていたが、書いていて恥ずかしくなるような多数の問題を抱えていた。 柔軟性が乏しい: 32bit整数や文字列などの単純な値しか格納で…</summary></entry><entry><id>https://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="https://fumieval.hatenablog.com/entry/2019/08/15/195448"/><summary type="html">Minecraft 1.14 &#34;Village and Pillage&#34;は、サブタイトルの通り村人と略奪者をテーマにしたアップデートだ。 主な楽しみ方 村人の取引システムが一新され、以前よりもバリエーションに富み、かつリーズナブルな取引ができるようになった。余ったアイテムを換金したり、有益なアイテムを入手できるようになるだろう。 ランタン、焚火などの新たな光源や、壁や階段の変種、さらには鐘なども追加され、建築の楽しみも大きく増した。だが、良いことばかりではない――新たなイリジャー(邪悪な村人)、ピリジャーが出現するようになったのだ。条件を満たすと発生する襲撃から村を守る死闘、そして安全な拠点づ…</summary></entry><entry><id>https://ccvanishing.hateblo.jp/entry/2019/07/30/112634</id><title type="text">CloudNative Days Tokyo 2019 登壇こぼれ話 #CNDT2019</title><updated>2019-07-30T11:26:34+09:00</updated><author><name>y_taka_23</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://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-29T04:03:51+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://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://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>y_taka_23</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>y_taka_23</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://fumieval.hatenablog.com/entry/2019/06/13/155557</id><title type="text">Traversable API</title><updated>2019-06-13T15:55:57+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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] 悪くはないが、この型はたとえば「[&#34;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>y_taka_23</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:36:48+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>https://fumieval.hatenablog.com/entry/2019/04/01/185927</id><title type="text">楽園へ行きたい</title><updated>2019-04-01T18:59:27+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2019/04/01/185927"/><summary type="html">楽園へ行きたい。 森と平原に囲まれた、街のはずれの小屋に住みたい。 朝は、小鳥たちのさえずりと窓から射し込む陽の光で目覚めたい。 昼は、コーヒーと焼き菓子を用意して一服したい。 夜は、天の河の向こうに思いを馳せながら眠りたい。 月曜日は大学に行き、エルフの先生の下で言語学を学びたい。 火曜日は研究室にこもり、ドラゴンの教授と研究に没頭したい。 水、木曜日は道具鍛治と修繕の仕事をしたい。 金曜日は都に向かい、品を売って食材と情報を仕入れたい。 土曜日は酒場に集まり、仲間たちと杯を交わしたい。 日曜日は使い魔を連れ、公園をゆったり散歩したい。 春は、花々を眺めながら、渡り鳥たちにしばしの別れを告げ…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2019/03/21/172101</id><title type="text">特級シリアライズライブラリ、winery 1.0解禁</title><updated>2019-03-21T17:21:01+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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://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>y_taka_23</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>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-26T19:58:06+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/22/193916</id><title type="text">Kubernetes Meetup Tokyo #16 で Scheduling Framework について話してきました</title><updated>2019-02-22T19:39:16+09:00</updated><author><name>y_taka_23</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>https://fumieval.hatenablog.com/entry/2019/02/15/181806</id><title type="text">旅のチェックリスト</title><updated>2019-02-15T18:18:06+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2019/02/15/181806"/><summary type="html">筆者が旅に出る際に確認する項目をまとめた。 事前の準備 渡航ビザ: 必要な場合もあるので事前に確かめよう。 ESTA(アメリカの場合): どんな理由であれUSに入国する場合申請する必要がある。大抵すぐ承認されるが、遅くとも出発の72時間前に済ませるべきである。 宿: 好みに応じてホテルでもAirBnBなどで民泊を予約しても。後者はキッチンが用意されているところもある。 交通手段: 電車は大抵の場合当日で大丈夫だが、もちろん船舶や航空機の場合は予約が必須である。 冷蔵庫の整理: 日持ちしないものは消費してしまおう。 携帯するもの 財布: 財布は現金やカードを収納する。リスク回避の観点から財布は省…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2019/02/12/191002</id><title type="text">ある期間内に更新されたデータを素早く検索できるモデル</title><updated>2019-02-12T19:10:02+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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:46:38+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 &#34;goodbye!&#34; 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-25T01:51:19+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>https://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="https://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://fumieval.hatenablog.com/entry/2018/12/27/213853</id><title type="text">戊戌の追憶</title><updated>2018-12-27T21:38:53+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2018/12/27/213853"/><summary type="html">この記事は、筆者が過ごした2018年を簡潔に振り返り、その経験を糧とすることを狙う。 1月 第二鰓弓由来側頸嚢胞という先天異常が原因で首が化膿し、激痛に苦しんでいた。対人関係のトラブルなどもあり軽い錯乱状態にあったのか、自分が知らない間に高い買い物をすることがあった。 drinkery: Boozy streaming library というストリーム処理ライブラリを作った。当初はすべて酒関係の用語を用いていたが、批判を受けてそこはやめた。今思えばそれで正解だった気がする。 パフォーマンスはモナディックなAPIを持つライブラリの中ではトップクラスで、双方向性や多入力多出力のような発展的な機能も…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2018/12/21/201108</id><title type="text">Elias-Fano encoding: 単調増加する数列をほぼ簡潔に表現する</title><updated>2018-12-21T20:11:08+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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>y_taka_23</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>y_taka_23</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://fumieval.hatenablog.com/entry/2018/10/31/150056</id><title type="text">「名前の束縛」という名の束縛</title><updated>2018-10-31T15:00:56+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2018/10/31/150056"/><summary type="html">実用的なプログラミングにおいて、名前と概念を結びつける「束縛」はほぼ必須の概念である。しかし、その言葉には大きな誤解と混乱が根付いていた。 事の発端となったのは「Haskellにおいては、変数は値を代入するものではなく、値に束縛するものである」という議論である*1 *2。しかし、これは大きな誤解を孕んでいる。言葉の定義に立ち返ってその誤解を解いていこう。 束縛とバインディング 実は「束縛」には二つの意味がある。一つは、数学的な意味での変数の束縛*3、もう一つは、識別子と実体の結合という意味での束縛*4だ。 前者は変数の導入と言い換えることもできる。ラムダ計算におけるラムダ抽象と変数の関係もこれ…</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:25:57+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/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://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="https://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://kurokawh.blogspot.com/2018/06/linuxcygwin-unzip-error-invalid.html</id><title type="text">[linux][cygwin] unzipコマンドで &#34;error:  invalid compressed data to inflate&#34; というエラーメッセージがでたら？</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>https://fumieval.hatenablog.com/entry/2018/06/03/195024</id><title type="text">日持ちする直列化のためのライブラリ「winery」</title><updated>2018-06-03T19:50:24+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2018/06/03/195024"/><summary type="html">人類は、酒と共に発展してきたと言っても過言ではない。穀物や果実などを酒に変換することにより、糖を除く栄養を保ったまま、高い保存性を持たせることができる。酒は人々の喉を潤し、時に薬として使われた。 プログラミングにおいても、終了したら消えてしまうデータを、保存性の高いバイト列に変えたい場面がよくある。そのような操作を直列化(シリアライズ)と呼び、いくつかのアプローチが存在する。 コード生成タイプ Protocol Buffers、cap&#39;n&#39;protoなど データの構造を記述する言語(スキーマ)から、データ構造およびシリアライザ・デシリアライザをコードごと生成する。幅広い言語で使える一方、作れる…</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-04-27T02:09:41+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://ilyaletre.hatenablog.com/entry/2018/03/20/224320</id><title type="text">Haskellで再帰的な構文木にFix(不動点)を導入してみる</title><updated>2018-03-20T22:43:20+09:00</updated><author><name>ilyaletre</name></author><link href="https://ilyaletre.hatenablog.com/entry/2018/03/20/224320"/><summary type="html">まえおき 例によって僕の記事など読まなくても下記のリンクで解説されているので、 Haskell楽しいなと思う人はこちらをどうぞ。 An Introduction to Recursion Schemes 生きるのに疲れた人は半分白目のゆるい気持ちで以降を読んでね。 Haskellで抽象構文木 (AST) にメタデータを付与する 以前この記事でASTへのメタデータの埋め込み方について少し整理して、 下記のようなアプローチがあることを明らかにした。 メタデータを保存するための値コンストラクタをASTのブランチとして定義する メタデータを保存するラッパーを定義する 加えて Fixを使ってなんかファン…</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のカスタマイズ&amp;nbsp;

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

Requestのカスタマイズ

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

Responseの操作

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

エラーハンドリング 






単純なHTTP GETリクエスト
{-# LANGUAGE </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&#39;エラーで失敗する問題の対処方法</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 &#34; </summary></entry><entry><id>https://syocy.hatenablog.com/entry/2018/02/14/160833</id><title type="text">Haskellの実行バイナリにファイルを埋め込む</title><updated>2018-02-14T16:08:33+09:00</updated><author><name>syocy</name></author><link href="https://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://fumieval.hatenablog.com/entry/2018/02/11/185306</id><title type="text">HaskellでDiscordのBotを作る</title><updated>2018-02-11T18:53:06+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://fumieval.hatenablog.com/entry/2018/02/11/185306"/><summary type="html">Discordはゲーミング向けのテキストチャットと音声通話を兼ねるプラットフォームであり、「テキストチャンネル」と「ボイスチャンネル」の二種を好きなだけ作ることができる。もちろん音声を全チャンネルに常時垂れ流すわけには行かないので、通話するにはボイスチャンネルに参加するという手順を踏む必要がある。しかし、例えば誰かがやっているゲームに混ざろうとしてボイスチャンネルに参加しても、チャンネル外のユーザーにはいかなる通知も発生しないため、気づかれないままのことがよくある。 そこで、ボイスチャンネルに参加したとき、テキストチャンネルにその旨を投稿するボットを用意すれば、気軽に通話の合図を送れる。全員に…</summary></entry><entry><id>https://ilyaletre.hatenablog.com/entry/2018/01/03/185920</id><title type="text">Haskellで抽象構文木 (AST) にメタデータを付与する</title><updated>2018-01-03T18:59:20+09:00</updated><author><name>ilyaletre</name></author><link href="https://ilyaletre.hatenablog.com/entry/2018/01/03/185920"/><summary type="html">2018-01-04 追記: ここで全部語り尽くされている気がしたので、Labelling AST Nodes with locations なにもこんなブログ読むことはないのかもしれない。 megaparsecを使って構文解析器を書いている。 構文解析やっているとASTにソースファイルの位置情報とかをメタデータとして乗せたくなるが、 どんな感じで実装するのか調べた。 僕自身はどのアプローチをとるのか決まっていない。 問題 やりたいこと megaparsec, parsecなどのコンビネータライブラリはジェネレータ系のalex + happyと比べると幾分まともなエラーメッセージを吐くようにな…</summary></entry><entry><id>https://fumieval.hatenablog.com/entry/2017/12/24/202404</id><title type="text">ガバガバAltJSを作った(言語実装 Advent Calendar 2017)</title><updated>2017-12-24T20:24:04+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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>https://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="https://fumieval.hatenablog.com/entry/2017/12/19/203500"/><summary type="html">Haskellといえば一文字変数名、一文字変数名といえばHaskellという{{要出典}}ほどにHaskellでは一文字の変数名がよく使われている。これは名前を考えるのをサボっているとは限らない。多相性によって変数が具体的な性質を持たないがゆえに、具体的な名前がつけられないというのが主な理由だ。あるいは、適切な名前があっても、既存の名前と被っているという場合もある。かといって完全なランダムというわけでもないので、一文字変数名はどのように選べばいいか考察していこう。 a よくある種: * アルファベットの最初であるaは汎用性が高い。型変数に使うのが王道だ。値レベルの変数として単体で使うことは意外…</summary></entry><entry><id>https://ilyaletre.hatenablog.com/entry/2017/12/17/212053</id><title type="text">Left Recursionの悪夢再び</title><updated>2017-12-17T21:20:53+09:00</updated><author><name>ilyaletre</name></author><link href="https://ilyaletre.hatenablog.com/entry/2017/12/17/212053"/><summary type="html">はじめに Happyで生成したパーサのコンパイル遅すぎてもう限界だったのでparser combinatorに戻ってきた。 そしてまた現れたのだ、やつが。。。。 問題 やろうとしてることは以前と変わらない。 SML Definitionを読んで型の注釈を表す式 ty を解析しようとしているが、 左無限再帰が起きてしまって解析が終了しないというもの。 ty ::= tyvar (1) type variable such as &#39;a { tyrow i } (2) record type tyseq longtycon (3) type constructor with type argumen…</summary></entry><entry><id>https://ilyaletre.hatenablog.com/entry/2017/12/10/195016</id><title type="text">GHCの中間言語Coreへの脱糖を覗き見る</title><updated>2017-12-10T19:50:16+09:00</updated><author><name>ilyaletre</name></author><link href="https://ilyaletre.hatenablog.com/entry/2017/12/10/195016"/><summary type="html">Haskell (その3) Advent Calendar 2017 11日目の記事。(予約投稿知らなかったのでフライングになった) GHCがコンパイルの途中で中間表現として用いるCoreの生成っぷりを観察する。 観察して、あーはいはいなるほどね(わかってない)、と言うだけになりそう。 はじめに GHCはHaskellのソースコードを低レベルなコードへとコンパイルする過程で様々なpass(コンパイルのステージ)を通じてプログラムデータを変換する。 俯瞰図は下記のリンクに詳しい。 Compiling one module: HscMain 僕がGHCの話をどこかで聞きかじってかっこいいな、と思っ…</summary></entry><entry><id>https://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-03T09:52:10+09:00</updated><author><name>syocy</name></author><link href="https://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://fumieval.hatenablog.com/entry/2017/10/17/172322</id><title type="text">ステートマシン猛レース</title><updated>2017-10-17T17:23:22+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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://fumieval.hatenablog.com/entry/2017/10/11/230117</id><title type="text">WindowsでのHaskell開発環境構築(2017年秋版)</title><updated>2017-10-11T23:01:17+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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://ilyaletre.hatenablog.com/entry/2017/09/30/193043</id><title type="text">SMLの関数適用を構文解析する時の問題</title><updated>2017-09-30T19:30:43+09:00</updated><author><name>ilyaletre</name></author><link href="https://ilyaletre.hatenablog.com/entry/2017/09/30/193043"/><summary type="html">まだ構文解析器で苦労している。 今回も詰まっているのは構文のconflict。 問題 これが関数適用 app : exp exp これが二項演算子適用 infixapp : exp vid exp この時に入力を x y z とすると２つの解釈ができてしまうことになる。 ((x y) z) とするネストした関数適用なのか x y z とする二項演算子の適用なのかParserが判断つけられない。 前者ならreduceするが後者ならshiftする。 なのでこれはshift/reduce conflictが起きていると言える。 happyはデフォルトでshiftするので二項演算子として解釈される。 …</summary></entry><entry><id>https://ilyaletre.hatenablog.com/entry/2017/09/24/234126</id><title type="text">好きなプログラミング言語の好きなところについて思った</title><updated>2017-09-24T23:41:26+09:00</updated><author><name>ilyaletre</name></author><link href="https://ilyaletre.hatenablog.com/entry/2017/09/24/234126"/><summary type="html">改めて最近実感すること。 Haskell, Elm, Clojureほんと好き。 Scala勉強しなきゃなーと思いながらClojureを触ってしまうことが多かったのだけれど、 その理由が少しずつわかってきた。 いい言語たち いままで少しだけ触れてきたJava, Python, Scala, Goはいずれもとても大きなユーザを抱えている。 どの言語もたくさんのユーザを得るために現場で使えるようなエコシステムをどんどん投下してあっという間に大きなユーザベースを獲得した。 プログラミングのしやすさを大事にして、誰でもすんなり入門できるように設計されている。 僕が入門できるくらいだから本当に敷居が低く…</summary></entry><entry><id>https://syocy.hatenablog.com/entry/2017/08/27/003035</id><title type="text">GoのTickerみたいなやつをHaskellで作った</title><updated>2017-08-27T00:30:35+09:00</updated><author><name>syocy</name></author><link href="https://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>https://syocy.hatenablog.com/entry/2017/08/14/235830</id><title type="text">HaskellとJSON、そしてレコード型</title><updated>2017-08-14T23:58:30+09:00</updated><author><name>syocy</name></author><link href="https://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>https://fumieval.hatenablog.com/entry/2017/08/06/154901</id><title type="text">FRPクライシス</title><updated>2017-08-06T15:49:01+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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>https://fumieval.hatenablog.com/entry/2017/08/02/230422</id><title type="text">快速のExtensible effects</title><updated>2017-08-02T23:04:22+09:00</updated><author><name>Fumiaki Kinoshita</name></author><link href="https://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://ilyaletre.hatenablog.com/entry/2017/07/03/163749</id><title type="text">左再帰を含む構文解析むずい</title><updated>2017-07-03T16:37:49+09:00</updated><author><name>ilyaletre</name></author><link href="https://ilyaletre.hatenablog.com/entry/2017/07/03/163749"/><summary type="html">やろうとしていること Haskellのparsecを使ってSMLの構文を解析し構文木を生成する。 やっていること SMLの構文解析はいろいろステップがある。 リテラル (special constants) 識別子 (identifier) 型注釈 !!イマココ!! パターンマッチ 式 宣言 モジュール構文 リテラルや識別子はなんとか倒して、いま型注釈の解析に取り組んでいるところ。 苦戦しているところ この型注釈の構文解析で例の問題に突き当たった。 左再帰問題だ。 SMLの型注釈の構文はこんな感じ。 ty ::= tyvar { &lt;tyrow&gt; } tyseq longtycon ty -&gt; …</summary></entry><entry><id>https://ilyaletre.hatenablog.com/entry/2017/05/21/162855</id><title type="text">Haskellerの好きなところ</title><updated>2017-05-21T16:28:55+09:00</updated><author><name>ilyaletre</name></author><link href="https://ilyaletre.hatenablog.com/entry/2017/05/21/162855"/><summary type="html">僕はHaskellが好き。 なんだけど、同じくらいHaskellもくもく会の常連の人達が好き。 ちょっとした型についての質問から、いつの間にかホワイトボード上で証明とか書き出して「あー、ほんとだー、そういうことかー」って言ってる感じが好き。 解らないことがあったら自分で検証するっていう、問題に対する誠実で真っ直ぐな態度を持っている人達が好き。 Haskellではそういう解らないところを形式的に検証する方法や知識がよく整備されていると思う。(とても難しいものもあるけど) きっと他のコミュニティにもそういう人はたくさんいる。でもHaskellもくもく会にはそういう人達が間違いなくいるのを僕は知って…</summary></entry><entry><id>https://ilyaletre.hatenablog.com/entry/2017/05/20/174125</id><title type="text">Haskellの代数データ型をJava的なインタフェースと捉える</title><updated>2017-05-20T17:41:25+09:00</updated><author><name>ilyaletre</name></author><link href="https://ilyaletre.hatenablog.com/entry/2017/05/20/174125"/><summary type="html">Haskellの代数データ型は僕にとってJavaのインタフェースに近い。 データ型がインタフェースでそのデータを受け取る関数がインタフェースのメソッドに相当する。 データをパターンマッチで分解して値コンストラクタ別の関数定義をするのは、 インタフェースに対する実装を与えているものだと考えている。 data Maybe a mapMaybe :: (a -&gt; b) -&gt; Maybe a -&gt; Maybe b Maybe aというデータ型があるとする。これがインターフェース。 mapMaybeという関数があるとする。これがメソッド。 インタフェースに実装を与えていく。 まずはデータ構造としてのイン…</summary></entry><entry><id>https://syocy.hatenablog.com/entry/2017/05/20/025021</id><title type="text">Haskellは真面目なアプリケーション開発に向いている</title><updated>2017-05-20T02:50:21+09:00</updated><author><name>syocy</name></author><link href="https://syocy.hatenablog.com/entry/2017/05/20/025021"/><summary type="html">qiita.com ↑の記事で（主題ではないと思うものの）Haskellの批判に結構な分量が割かれていて、その批判のなかに「ちょっと違うんじゃないかな」という点がいくつかあったので反論ぽいことを書きます。 &#34;Haskell は真面目なアプリケーション開発には向いてない&#34;について これには多分いくつか事例を挙げればよくて、 Facebook ではスパム等の攻撃と戦うためのシステムを Haskell で作っています。 Fighting spam with Haskell | Engineering Blog | Facebook Code | Facebook (この記事を書いている Simon …</summary></entry><entry><id>https://syocy.hatenablog.com/entry/2017/04/26/005415</id><title type="text">超技術書典でGHCJSの本を出します</title><updated>2017-04-26T00:54:15+09:00</updated><author><name>syocy</name></author><link href="https://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>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
&amp;lt;table border&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;th&amp;gt;name&amp;lt;/th&amp;gt;    &amp;lt;th&amp;gt;sex&amp;lt;/th&amp;gt;    &amp;lt;th&amp;gt;age&amp;lt;/th&amp;gt;
  &amp;lt;/tr&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;Taro Yamada&amp;lt;/td&amp;gt</summary></entry><entry><id>https://syocy.hatenablog.com/entry/haskell-library-2016</id><title type="text">Haskellライブラリ所感2016</title><updated>2016-12-07T00:00:45+09:00</updated><author><name>syocy</name></author><link href="https://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>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 &amp;nbsp; &amp;nbsp;シンボリックリンクを辿る
-r &amp;nbsp;DIR &amp;nbsp; &amp;nbsp;シンボリックリンクは辿らない

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

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

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

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


使用例</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

&#34;/bin/tcsh&#34;とすることでデフォルトのシェルが切り替わる
</summary></entry><entry><id>https://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="https://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>https://syocy.hatenablog.com/entry/2016/08/28/175500</id><title type="text">続・Haskellの最近の例外ハンドリング</title><updated>2016-08-28T17:55:00+09:00</updated><author><name>syocy</name></author><link href="https://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>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

&#34;--system-ghc&#34;は省略可能。インストール済みの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&#39;t built」という表示が出てしまいました。



このときターミナルには以下のようなログが出力されていました。
% stack exec -- yesod devel
Yesod devel server. Type &#39;quit&#39; 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>https://syocy.hatenablog.com/entry/2016/07/02/174426</id><title type="text">Haskellの最近の例外ハンドリング</title><updated>2016-07-02T17:44:26+09:00</updated><author><name>syocy</name></author><link href="https://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>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/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 &#39;-std=c++11&#39;


-stdオプションで&#34;c++11&#34;を指定しても、認識してくれません。
本家のサイトによると、&#39;-std=c++11&#39;オプションは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>https://kurokawh.blogspot.com/2015/11/haskellstack-stack-exec-ghcicouldnt.html</id><title type="text">[haskell][stack] stack exec ghciで”Couldn&#39;t match expected type&#34;エラーが発生する問題の対処</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でソースをロードしようとすると&#34;Couldn&#39;t match expected type: xxxxx&#34;とエラーが発生する問題に遭遇しました。
ネットの情報を参考に解決することができたのでその手順をまとめておきます。


問題：
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>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コマンドを実行する度に&#34;password:&#34;というプロンプトが表示されてパスワードの入力を求められてしまいます。


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

OpenSSH_7.0p1, OpenSSL 1.0.2d 9 Jul 2015
OpenSSH_7.1p1, OpenSSL 1.0.2d 9 Jul </summary></entry></feed>