tag:crieit.net,2005:https://crieit.net/tags/Haskell/feed 「Haskell」の記事 - Crieit Crieitでタグ「Haskell」に投稿された最近の記事 2023-12-25T21:15:23+09:00 https://crieit.net/tags/Haskell/feed tag:crieit.net,2005:PublicArticle/18684 2023-12-24T14:44:58+09:00 2023-12-25T21:15:23+09:00 https://crieit.net/posts/Haskell-o-6587c55a0cd8c Haskellを練習しようぜ(^o^)?<その1o0> <h1 id="前の記事"><a href="#%E5%89%8D%E3%81%AE%E8%A8%98%E4%BA%8B">前の記事</a></h1> <p>📖 <a href="https://crieit.net/posts/Haskell-Ubuntu">Haskell を Ubuntu にインストールできねーの(^〜^)?</a></p> <h1 id="情報"><a href="#%E6%83%85%E5%A0%B1">情報</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://github.com/muzudho/kifuwarabe-shogi-haskell">kifuwarabe-shogi-haskell</a></p> <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↓ とほほ を見ながら ハスケルを自習しようぜ?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.tohoho-web.com/ex/haskell.html#list">とほほのHaskell入門</a></p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 じゃあ コンソールで将棋盤を表示してみてくれだぜ」</p> <p>🗒 <code>view_shogiban.hs</code> :</p> <pre><code class="hs"><br /></code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ あれっ、ハスケルで 日本語入力できないぜ?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://mebee.info/2020/10/26/post-20987/">ubuntu20.04.1 vscodeで日本語入力ができない</a></p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 snap でインストールした VSCode は、日本語入力ができないらしいわよ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 アンインストールは つらい、なにかアップデートする方法はないか?」</p> <p><code>Japanese Language Pack for Visual Studio Code</code></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 試しに拡張を入れてみようぜ?」</p> <p><code>[Ctrl] + [Shift] + [P]</code> で <code>Configure Display Language</code> で日本語へ。</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 コマンドを使って設定もして、VSCodeも再起動」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ダメだ、何も変わらん。<br /> フロント・エンド・プロセッサーが反応してない」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://ch-random.net/post/458/">【新入生夏記事】Ubuntu の VSCode で 日本語入力 ができない問題</a></p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ↑ <code>Ubuntu Software</code> や <code>snap</code> は、土台がダメみたいよ」</p> <h1 id="Visual Studio Code をアンインストール"><a href="#Visual+Studio+Code+%E3%82%92%E3%82%A2%E3%83%B3%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">Visual Studio Code をアンインストール</a></h1> <pre><code class="bash">sudo snap remove code </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ Visual Studio Code をアンインストールするぜ」</p> <h1 id="Visual Studio を再インストール"><a href="#Visual+Studio+%E3%82%92%E5%86%8D%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">Visual Studio を再インストール</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://code.visualstudio.com/download">Download Visual Studio Code</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ Ubuntu なんで、 <code>.deb</code> を選ぶぜ。デビアンという意味かな」</p> <p><code>code_1.85.1-1702462158_amd64.deb</code></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ フォルダーなのか、圧縮ファイルなのか、なにかダウンロードしたが」</p> <pre><code class="bash">sudo apt install code_1.85.1-1702462158_amd64.deb </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ターミナルを開いて実行」</p> <pre><code class="bash">muzudho@muzudho-MS-7B09:~/Downloads$ sudo apt install code_1.85.1-1702462158_amd64.deb Reading package lists... Done Building dependency tree... Done Reading state information... Done E: Unable to locate package code_1.85.1-1702462158_amd64.deb </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ うーん?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://askubuntu.com/questions/216287/unable-to-install-files-with-apt-get-unable-to-locate-package">Unable to install files with apt-get: "unable to locate package" [duplicate]</a></p> <pre><code class="bash">sudo apt-get update sudo apt install code_1.85.1-1702462158_amd64.deb </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 変わらんなあ」</p> <pre><code class="bash">sudo apt install ./code_1.85.1-1702462158_amd64.deb </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ カレント・ディレクトリの指定を忘れていた。これでインストールが始まった」</p> <pre><code class="bash">code </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ よし、振り出しに戻ったぜ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 うわっ、日本語版の GUI が出てきた、かっこ悪いから 英語版に戻そう」</p> <p><code>[Ctrl] + [Shift] + [P]</code> で <code>Configure Display Language</code> で英語へ。</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 よし、 Visual Studio Code は英語表示で、日本語入力できるようになったぜ」</p> <h1 id="将棋盤を表示しよう"><a href="#%E5%B0%86%E6%A3%8B%E7%9B%A4%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%97%E3%82%88%E3%81%86">将棋盤を表示しよう</a></h1> <p>🗒 <code>view_shogiban.hs</code> :</p> <pre><code class="hs">{- ビュー / 将棋盤 -} main = putStrLn "+--+--+--+--+--+--+--+--+--+" </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ さまざまなことがわからないので、将棋盤の上辺を表示したいぜ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://wiki.haskell.org/Haskell_in_5_steps">Haskell in 5 steps</a></p> <pre><code class="bash"># コンパイル ghc -o view_shogiban view_shogiban.hs # 実行 ./view_shogiban </code></pre> <p>Output:</p> <pre><code class="plaintext">+--+--+--+--+--+--+--+--+--+ </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ おー、表示されたぜ」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 Haskell で複数行文字列って どうやってコーディングすんの?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/22918837/how-can-i-write-multiline-strings-in-haskell">How can I write multiline strings in Haskell?</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ラインフィードと デリミタでやるらしい」</p> <pre><code class="hs">{- ビュー / 将棋盤 -} main = putStrLn " 9 8 7 6 5 4 3 2 1\n\ \ +--+--+--+--+--+--+--+--+--+\n\ \ 1 | | | | | | | | | |\n\ \ +--+--+--+--+--+--+--+--+--+\n\ \ 2 | | | | | | | | | |\n\ \ +--+--+--+--+--+--+--+--+--+\n\ \ 3 | | | | | | | | | |\n\ \ +--+--+--+--+--+--+--+--+--+\n\ \ 4 | | | | | | | | | |\n\ \ +--+--+--+--+--+--+--+--+--+\n\ \ 5 | | | | | | | | | |\n\ \ +--+--+--+--+--+--+--+--+--+\n\ \ 6 | | | | | | | | | |\n\ \ +--+--+--+--+--+--+--+--+--+\n\ \ 7 | | | | | | | | | |\n\ \ +--+--+--+--+--+--+--+--+--+\n\ \ 8 | | | | | | | | | |\n\ \ +--+--+--+--+--+--+--+--+--+\n\ \ 9 | | | | | | | | | |\n\ \ +--+--+--+--+--+--+--+--+--+\n" </code></pre> <p>Output:</p> <pre><code class="plaintext">muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban 9 8 7 6 5 4 3 2 1 +--+--+--+--+--+--+--+--+--+ 1 | | | | | | | | | | +--+--+--+--+--+--+--+--+--+ 2 | | | | | | | | | | +--+--+--+--+--+--+--+--+--+ 3 | | | | | | | | | | +--+--+--+--+--+--+--+--+--+ 4 | | | | | | | | | | +--+--+--+--+--+--+--+--+--+ 5 | | | | | | | | | | +--+--+--+--+--+--+--+--+--+ 6 | | | | | | | | | | +--+--+--+--+--+--+--+--+--+ 7 | | | | | | | | | | +--+--+--+--+--+--+--+--+--+ 8 | | | | | | | | | | +--+--+--+--+--+--+--+--+--+ 9 | | | | | | | | | | +--+--+--+--+--+--+--+--+--+ </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ おー、こういう感じか」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 じゃー、ごっついの もっさり 作っていきますか」</p> <h1 id="フォントの設定"><a href="#%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A">フォントの設定</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 日本語と 半角文字の横幅の 桁が揃わない。<br /> VSCodeのフォントを 等幅フォントの mplus code にしたい。できるの?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://qiita.com/b2ox/items/2babce6e8c053fc4a0d6">VSCodeのフォントにMigu 1Mを使う</a></p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ↑ フォントの設定は できるみたいだが……」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 じゃあ MPlus のフォントを Ubuntu へインストールできるかどうかか」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://mplusfonts.github.io/">M+Fonts</a><br /> 📖 <a target="_blank" rel="nofollow noopener" href="https://github.com/coz-m/MPLUS_FONTS/tree/master/fonts/otf">M+Fonts / otf</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ otf をダウンロードすればいいのかだぜ?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 Git Hub 上の <code>Mplus1Code-Regular.otf</code> リンクを コンコン クリックして進んでいったら インストールまで行けた 便利だな」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 VSCode のメインメニューから <code>[File] - [Preferences] - [Settings]</code>。<br /> Font Family の先頭に <code>'M Plus 1 Code',</code> を追加したけど、どうか?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 Visual Studio Code を全部閉じて再起動。<br /> よしいけた」</p> <h1 id="将棋盤のレイアウトを考える"><a href="#%E5%B0%86%E6%A3%8B%E7%9B%A4%E3%81%AE%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E3%82%92%E8%80%83%E3%81%88%E3%82%8B">将棋盤のレイアウトを考える</a></h1> <pre><code class="plaintext">muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban 飛 角 金 銀 桂 香 歩 [nnn move(s) / sente / 0 repeat(s)] +-----+-----+-----+-----+-----+-----+-----+ | 2 | 2 | 4 | 4 | 4 | 4 | 18 | +-----+-----+-----+-----+-----+-----+-----+ 一 二 三 四 五 六 七 八 九 +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 1 |[香> | |[歩> |[歩> |[歩> |[歩> | <歩]| | <香]| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 2 |[桂> |[角> |[歩> | | | | <歩]| <飛]| <桂]| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 3 |[銀> | |[歩> | | | | <歩]| | <銀]| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 4 |[金> | |[歩> | | | | <歩]| | <金]| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 5 |[玉> | |[歩> | | | | <歩]| | <玉]| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 6 |[金> | |[歩> | | | | <歩]| | <金]| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 7 |[銀> | |[歩> | | | | <歩]| | <銀]| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 8 |[桂> |[飛> |[歩> | | | | <歩]| <角]| <桂]| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 9 |[香> | |[歩> | | | | <歩]| | <香]| +-----+-----+-----+-----+-----+-----+-----+-----+----+ 歩 香 桂 銀 金 角 飛 +-----+-----+-----+-----+-----+-----+-----+ | 18 | 4 | 4 | 4 | 4 | 4 | 4 | +-----+-----+-----+-----+-----+-----+-----+ </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ フーム どうすれば 見やすいかな?」</p> <pre><code class="plaintext">uzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban 飛 角 金 銀 桂 香 歩 [nnn move(s) / sente / 0 repeat(s)] +-----+-----+-----+-----+-----+-----+-----+ | 2 | 2 | 4 | 4 | 4 | 4 | 18 | +-----+-----+-----+-----+-----+-----+-----+ 一 二 三 四 五 六 七 八 九 +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 1 | 香> | | 歩> | | | | <歩 | | <香 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 2 | 桂> | 角> | 歩> | | | | <歩 | <飛 | <桂 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 3 | 銀> | | 歩> | | | | <歩 | | <銀 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 4 | 金> | | 歩> | | | | <歩 | | <金 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 5 | 玉> | | 歩> | | | | <歩 | | <玉 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 6 | 金> | | 歩> | | | | <歩 | | <金 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 7 | 銀> | | 歩> | | | | <歩 | | <銀 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 8 | 桂> | 飛> | 歩> | | | | <歩 | <角 | <桂 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 9 | 香> | | 歩> | | | | <歩 | | <香 | +-----+-----+-----+-----+-----+-----+-----+-----+----+ 歩 香 桂 銀 金 角 飛 +-----+-----+-----+-----+-----+-----+-----+ | 18 | 4 | 4 | 4 | 4 | 4 | 4 | +-----+-----+-----+-----+-----+-----+-----+ </code></pre> <pre><code class="plaintext">muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban 飛 角 金 銀 桂 香 歩 [nnn move(s) / sente / 0 repeat(s)] +-----+-----+-----+-----+-----+-----+-----+ | 2 | 2 | 4 | 4 | 4 | 4 | 18 | +-----+-----+-----+-----+-----+-----+-----+ 一 二 三 四 五 六 七 八 九 +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 1 |香> | |歩> | | | | <歩| | <香| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 2 |桂> |角> |歩> | | | | <歩| <飛| <桂| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 3 |銀> | |歩> | | | | <歩| | <銀| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 4 |金> | |歩> | | | | <歩| | <金| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 5 |玉> | |歩> | | | | <歩| | <玉| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 6 |金> | |歩> | | | | <歩| | <金| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 7 |銀> | |歩> | | | | <歩| | <銀| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 8 |桂> |飛> |歩> | | | | <歩| <角| <桂| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 9 |香> | |歩> | | | | <歩| | <香| +-----+-----+-----+-----+-----+-----+-----+-----+----+ 歩 香 桂 銀 金 角 飛 +-----+-----+-----+-----+-----+-----+-----+ | 18 | 4 | 4 | 4 | 4 | 4 | 4 | +-----+-----+-----+-----+-----+-----+-----+ </code></pre> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 入り組んだときに 見やすいかどうかが 重要じゃないの?」</p> <pre><code class="plaintext">uzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban WCSC33 決勝6回戦 ▲ dlshogi with H vs ▽ やねうら王 飛 角 金 銀 桂 香 歩 [199 move(s) / ▲2一金 / n repeat(s)] +-----+-----+-----+-----+-----+-----+-----+ | | | | 1 | | | | +-----+-----+-----+-----+-----+-----+-----+ 一 二 三 四 五 六 七 八 九 +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 1 |玉> |角> | <香| |角> | |と> | | | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 2 | <金| |歩> |桂> | | <金| | <飛| | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 3 | <全| | |歩> | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 4 | | | | | | <歩| <金| | | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 5 | | | <銀| <桂|歩> | | <歩| | <玉| +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 6 | | | |歩> | |竜> | | <桂| | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 7 | | | | | | | <香| <歩|金> | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 8 | | <全| | | | |歩> | <銀| | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 9 | | | |歩> | | <歩| | | <香| +-----+-----+-----+-----+-----+-----+-----+-----+----+ 歩 香 桂 銀 金 角 飛 +-----+-----+-----+-----+-----+-----+-----+ | 7 | 1 | | | | | | +-----+-----+-----+-----+-----+-----+-----+ </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 駒の漢字が 縦に揃ってないのも気になるな」</p> <pre><code class="plaintext">muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban WCSC33 決勝6回戦 ▲ dlshogi with H vs ▽ やねうら王 飛 角 金 銀 桂 香 歩 [199 move(s) / ▲2一金 / n repeat(s)] +-----+-----+-----+-----+-----+-----+-----+ | | | | 1 | | | | +-----+-----+-----+-----+-----+-----+-----+ 一 二 三 四 五 六 七 八 九 +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 1 | 玉> : 角> : <香 : : 角> : : と> : : | + - - + - - + - - + - - + - - + - - + - - + - - + - - + 2 | <金 : : 歩> : 桂> : : <金 : : <飛 : | + - - + - - + - - + - - + - - + - - + - - + - - + - - + 3 | <全 : : : 歩> : : : : : | + - - + - - + - - + - - + - - + - - + - - + - - + - - + 4 | : : : : : <歩 : <金 : : | + - - + - - + - - + - - + - - + - - + - - + - - + - - + 5 | : : <銀 : <桂 : 歩> : : <歩 : : <玉 | + - - + - - + - - + - - + - - + - - + - - + - - + - - + 6 | : : : 歩> : : 竜> : : <桂 : | + - - + - - + - - + - - + - - + - - + - - + - - + - - + 7 | : : : : : : <香 : <歩 : 金> | + - - + - - + - - + - - + - - + - - + - - + - - + - - + 8 | : <全 : : : : : 歩> : <銀 : | + - - + - - + - - + - - + - - + - - + - - + - - + - - + 9 | : : : 歩> : : <歩 : : : <香 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 歩 香 桂 銀 金 角 飛 +-----+-----+-----+-----+-----+-----+-----+ | 7 | 1 | | | | | | +-----+-----+-----+-----+-----+-----+-----+ ``` ![ramen-tabero-futsu2.png](https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png) 「 ↑ 盤の方を点線にしてみたり」 ```plaintext muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban WCSC33 決勝6回戦 ▲ dlshogi with H vs ▽ やねうら王 飛 角 金 銀 桂 香 歩 [199 move(s) / ▲2一金 / n repeat(s)] +-----+-----+-----+-----+-----+-----+-----+ | | | | 1 | | | | +-----+-----+-----+-----+-----+-----+-----+ 一 二 三 四 五 六 七 八 九 +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 1 | 玉> ・ 角> ・ ・ ・ と> ・ ・ | + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + 2 | ・ 桂> ・ ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + 3 | ・ ・ ・ ・ ・ | + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + 4 | ・ ・ ・ ・ ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + 5 | ・ ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + 6 | ・ ・ ・ 歩> ・ ・ 竜> ・ ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + 7 | ・ ・ ・ ・ ・ ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + 8 | ・ ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + ・ + 9 | ・ ・ ・ 歩> ・ ・ +-----+-----+-----+-----+-----+-----+-----+-----+-----+ 歩 香 桂 銀 金 角 飛 +-----+-----+-----+-----+-----+-----+-----+ | 7 | 1 | | | | | | +-----+-----+-----+-----+-----+-----+-----+ ``` ![ramen-tabero-futsu2.png](https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png) 「 ↑ 半角の中点もあるが」 ![kifuwarabe-futsu.png](https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png) 「 将棋は罫線が多すぎでは? 囲碁みたいに 交点にしたらどうだぜ?」 ```plaintext muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban WCSC33 決勝6回戦 ▲ dlshogi with H vs ▽ やねうら王 飛 角 金 銀 桂 香 歩 [199 move(s) / ▲2一金 / n repeat(s)] +----+----+----+----+----+----+----+ | | | | 1 | | | | +----+----+----+----+----+----+----+ 一 二 三 四 五 六 七 八 九 +----+----+----+----+----+----+----+----+----+ 1 | 玉> 角> <香 ・ 角> ・ と> ・ ・ | + + 2 |<金 ・ 歩> 桂> ・ <金 ・ <飛 ・ | + + 3 |<全 ・ ・ 歩> ・ ・ ・ ・ ・ | + + 4 | ・ ・ ・ ・ ・ <歩 <金 ・ ・ | + + 5 | ・ ・ <銀 <桂 歩> ・ <歩 ・ <玉 | + + 6 | ・ ・ ・ 歩> ・ 竜> ・ <桂 ・ | + + 7 | ・ ・ ・ ・ ・ ・ <香 <歩 金>| + + 8 | ・ <全 ・ ・ ・ ・ 歩> <銀 ・ | + + 9 | ・ ・ ・ 歩> ・ <歩 ・ ・ <香 | +----+----+----+----+----+----+----+----+----+ 歩 香 桂 銀 金 角 飛 +----+----+----+----+----+----+----+ | 7 | 1 | | | | | | +----+----+----+----+----+----+----+ </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 視認性が悪いのは どこからくるのかなあ」</p> <pre><code class="plaintext">muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban WCSC33 決勝6回戦 ▲ dlshogi with H vs ▽ やねうら王 飛 角 金 銀 桂 香 歩 [199 move(s) / ▲2一金 / n repeat(s)] +------+------+------+------+------+------+------+ | | | | 1 | | | | +------+------+------+------+------+------+------+ 一 二 三 四 五 六 七 八 九 +------+------+------+------+------+------+------+------+------+ 1 | 玉 | 角 |<<香<<| | 角 | | と | | | +------+------+------+------+------+------+------+------+------+ 2 |<<金<<| | 歩 | 桂 | |<<金<<| |<<飛<<| | +------+------+------+------+------+------+------+------+------+ 3 |<<全<<| | | 歩 | | | | | | +------+------+------+------+------+------+------+------+------+ 4 | | | | | |<<歩<<|<<金<<| | | +------+------+------+------+------+------+------+------+------+ 5 | | |<<銀<<|<<桂<<| 歩 | |<<歩<<| |<<玉<<| +------+------+------+------+------+------+------+------+------+ 6 | | | | 歩 | | 竜 | |<<桂<<| | +------+------+------+------+------+------+------+------+------+ 7 | | | | | |<<香<<|<<歩<<| 金 | | +------+------+------+------+------+------+------+------+------+ 8 | |<<全<<| | | | 歩 |<<銀<<| | | +------+------+------+------+------+------+------+------+------+ 9 | | | | 歩 | |<<歩<<| | |<<香<<| +------+------+------+------+------+------+------+------+------+ 歩 香 桂 銀 金 角 飛 +------+------+------+------+------+------+------+ | 7 | 1 | | | | | | +------+------+------+------+------+------+------+ ``` ![ramen-tabero-futsu2.png](https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png) 「 ↑ 先手の駒の表示を うるさく してみたらどうだぜ?」 ![ohkina-hiyoko-futsu2.png](https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png) 「 もっと濃い網掛けはないの?」 ```plaintext muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban WCSC33 決勝6回戦 ▲ dlshogi with H vs ▽ やねうら王 飛 角 金 銀 桂 香 歩 [199 move(s) / ▲2一金 / n repeat(s)] +------+------+------+------+------+------+------+ | | | | 1 | | | | +------+------+------+------+------+------+------+ 一 二 三 四 五 六 七 八 九 +------+------+------+------+------+------+------+------+------+ 1 | 玉 >| 角 >| 香 | | 角 >| | と >| | | +------+------+------+------+------+------+------+------+------+ 2 | 金 | | 歩 >| 桂 >| | 金 | | 飛 | | +------+------+------+------+------+------+------+------+------+ 3 | 全 | | | 歩 >| | | | | | +------+------+------+------+------+------+------+------+------+ 4 | | | | | | 歩 | 金 | | | +------+------+------+------+------+------+------+------+------+ 5 | | | 銀 | 桂 | 歩 >| | 歩 | | 玉 | +------+------+------+------+------+------+------+------+------+ 6 | | | | 歩 >| | 竜 >| | 桂 | | +------+------+------+------+------+------+------+------+------+ 7 | | | | | | | 香 | 歩 | 金 >| +------+------+------+------+------+------+------+------+------+ 8 | | 全 | | | | 歩 >| 銀 | | | +------+------+------+------+------+------+------+------+------+ 9 | | | | 歩 >| | 歩 | | | 香 | +------+------+------+------+------+------+------+------+------+ 歩 香 桂 銀 金 角 飛 +------+------+------+------+------+------+------+ | 7 | 1 | | | | | | +------+------+------+------+------+------+------+ </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ いろいろ やってみたが 視認性は 悪かったぜ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 だったら 縦でいいのでは?」</p> <pre><code class="plaintext">muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu$ ./view_shogiban WCSC33 決勝6回戦 ▲ dlshogi with H vs ▽ やねうら王 9 8 7 6 5 4 3 2 1 [199 move(s) / ▲2一金 / n repeat(s)] +----+ +------+------+------+------+------+------+------+------+------+ 歩 | 7 | | | | | | | | 圭 | 金 | v玉 | 一 ▲玉 59 ▲香 99 77 13 ___ +----+ +------+------+------+------+------+------+------+------+------+ ▽玉 11 ▽香 *__ ___ ___ ___ 香 | 1 | | | 全 | | | | | | | v角 | 二 +----+ +------+------+------+------+------+------+------+------+------+ +----+ ▲飛 28 ___ ▲歩 ___ ___ ___ 桂 | | | | | | | 銀 | | | v歩 | 香 | 三 | | 飛 ▽飛 +66 ___ _46 _57 ___ +----+ +------+------+------+------+------+------+------+------+------+ +----+ _78 _87 _96 銀 | | | v歩 | | | v歩 | 桂 | | v歩 | v桂 | | 四 | | 角 ▲角 ___ ___ ___ ___ ___ ___ ___ ___ +----+ +------+------+------+------+------+------+------+------+------+ +----+ ▽角 12 15 ___ ___ ___ ___ ___ ___ 金 | | | | | | | v歩 | | | | v角 | 五 | | 金 ___ ___ ___ ___ ___ ___ +----+ +------+------+------+------+------+------+------+------+------+ +----+ ▲金 21 26 47 79 角 | | | 歩 | | | v竜 | | 歩 | | 金 | | 六 | 1 | 銀 ▽金 ___ ___ ___ ___ ▽歩 +17 _23 _34 +----+ +------+------+------+------+------+------+------+------+------+ +----+ ___ _55 _64 飛 | | | | 歩 | 香 | | 歩 | 金 | | | vと | 七 | | 桂 ▲銀 +82 53 88 *__ ___ ___ _94 +----+ +------+------+------+------+------+------+------+------+------+ +----+ ▽銀 ___ ___ ___ ___ *__ *__ *__ *__ *__ *__ | | 銀 | 歩 | 桂 | | | | 飛 | | 八 | | 香 *__ ___ ___ ___ ___ ___ +------+------+------+------+------+------+------+------+------+ +----+ ▲桂 +31 54 68 ___ ___ ___ ___ ___ ___ ___ | 香 | | 金 | | 玉 | | | | | 九 | | 歩 ▽桂 +24 ___ ___ ___ +------+------+------+------+------+------+------+------+------+ +----+ </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 位置情報も表示するなら こうかな」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 レイアウトはいったん これで確定して、モデルを作りましょう」</p> <h1 id="プロジェクト作成"><a href="#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E4%BD%9C%E6%88%90">プロジェクト作成</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 じゃあ プロジェクト・フォルダー作ったほうがいいのか」</p> <pre><code class="bash">mkdir shogi-project cd shogi-project cabal init --interactive </code></pre> <pre><code class="plaintext"> 📁 shogi-project ├── 📁 app │ └── 🗒 Main.hs ├── 📁 src │ └── 🗒 MyLib.hs ├── 🗒 CHANGELOG.md └── 🗒 shogi-project.cabal </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ このあと どうすんのか?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 <code>Main.hs</code> に何か書いてないかだぜ?」</p> <p>🗒 <code>app/Main.hs</code> :</p> <pre><code class="hs">module Main where import qualified MyLib (someFunc) main :: IO () main = do putStrLn "Hello, Haskell!" MyLib.someFunc </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ おー、 <code>do-notation</code> だ。<br /> 最後の <code>MyLib.someFunc</code> が分からんが」</p> <p>🗒 <code>src/MyLib.hs</code> :</p> <pre><code class="hs">module MyLib (someFunc) where someFunc :: IO () someFunc = putStrLn "someFunc" </code></pre> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 <code>someFunc</code> と表示するだけのライブラリーでは?」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 実行してみましょう!」</p> <pre><code class="bash">cabal build cabal run </code></pre> <p>Output:</p> <pre><code class="plaintext">Up to date Hello, Haskell! someFunc </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 全くそのとおりな結果だぜ」</p> <h2 id="print 文"><a href="#print+%E6%96%87">print 文</a></h2> <pre><code class="hs">module Main where import qualified MyLib (someFunc) main :: IO () main = do putStrLn "Hello, Haskell!" let x = 1 + 2 print x {- putStrLn x -} MyLib.someFunc </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ <code>putStrLen</code> と <code>print</code> の違いも分からん つら」</p> <h1 id="インプットどうする?"><a href="#%E3%82%A4%E3%83%B3%E3%83%97%E3%83%83%E3%83%88%E3%81%A9%E3%81%86%E3%81%99%E3%82%8B%EF%BC%9F">インプットどうする?</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://qiita.com/karszawa/items/ec0c01c81c22ce060405">Haskellで競技プログラミング IO編</a><br /> 📖 <a target="_blank" rel="nofollow noopener" href="https://minoki.github.io/ks-material/haskell/competitive.html">Haskellで競技プログラミング</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 競技プログラマが 詳しかったりするしな。読んだろ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.reddit.com/r/haskell/comments/i3f3ip/state_of_string_interpolation_in_haskell/">State of string interpolation in Haskell?</a><br /> 📖 <a target="_blank" rel="nofollow noopener" href="https://blog.sarabande.jp/post/101471543023">Haskell: 文字列の連結、繰り返し、置き換え</a><br /> 📖 <a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/10755852/how-to-concat-two-io-strings-in-haskell">How to concat two (IO) Strings in Haskell?</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 競技プログラマも よくわかってないようだ もっと調べよう」</p> <pre><code class="hs">module Main where import qualified MyLib (someFunc) main :: IO () main = do y putStrLn $ "入力は" ++ y -- 文字列連結するときは頭に $ を付ける return () </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 自分が何をやっているか分からないが これで動く」</p> <pre><code class="hs">module Main where import qualified MyLib (someFunc) main :: IO () main = do line -- print はダブルクォーテーションがついてしまう。そもそもデバッグ用らしい {- if line == "usi" then putStrLn "usiok" else putStrLn "panic" -} case line of "usi" -> putStrLn "usiok" "isready" -> putStrLn "readyok" "usinewgame" -> putStrLn "" _ -> putStrLn "resign" </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ケース文も こんな感じだが、ループは どうやって作る?」</p> <pre><code class="hs">module Main where import qualified MyLib (someFunc) main :: IO () main = do line case line of "usi" -> putStrLn "usiok" "isready" -> putStrLn "readyok" "usinewgame" -> putStrLn "" 'p' : 'o' : 's' : 'i' : 't' : 'i' : 'o' : 'n' : ' ' : _ -> putStrLn "" 'g' : 'o' : ' ' : _ -> putStrLn "resign" _ -> putStrLn "" usi :: IO () usi = do return () </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ハスケルの Startswith 狂ってんな」</p> <h2 id="ループどうする?"><a href="#%E3%83%AB%E3%83%BC%E3%83%97%E3%81%A9%E3%81%86%E3%81%99%E3%82%8B%EF%BC%9F">ループどうする?</a></h2> <pre><code class="hs">module Main where import qualified MyLib (someFunc) main :: IO () main = do line usi line usi :: String -> IO () usi line = do case line of "usi" -> putStrLn "usiok" "isready" -> putStrLn "readyok" "usinewgame" -> putStrLn "" 'p' : 'o' : 's' : 'i' : 't' : 'i' : 'o' : 'n' : ' ' : _ -> putStrLn "" 'g' : 'o' : ' ' : _ -> putStrLn "resign" _ -> putStrLn "" -- loop line usi line </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ これでループする。<br /> アプリケーションの終了って どうやるんだ?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 フォール・スルーすればいいのでは?」</p> <pre><code class="plaintext">module Main where import qualified MyLib (someFunc) main :: IO () main = do line usi line usi :: String -> IO () usi line = do case line of 'g' : 'o' : ' ' : _ -> do putStrLn "resign" "isready" -> do putStrLn "readyok" 'p' : 'o' : 's' : 'i' : 't' : 'i' : 'o' : 'n' : ' ' : _ -> do putStrLn "" "quit" -> do putStrLn "" -- 何もしないという処理は書けるか? "usi" -> do putStrLn "usiok" "usinewgame" -> do putStrLn "" _ -> do putStrLn "" if line == "quit" then return () else do -- loop line usi line </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ フォールスルーでアプリケーションを終了できるが、<br /> 何もしないという処理は どうやって書くんだぜ? Python の pass みたいなやつ」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 何もしない処理なんか 書くなって ことじゃないの?」</p> <pre><code class="hs">module Main where import qualified MyLib (someFunc) main :: IO () main = do line usi line usi :: String -> IO () usi line = do if line == "quit" then return () -- 関数を終了し、アプリケーションを終了する else do case line of 'g' : 'o' : ' ' : _ -> do putStrLn "resign" "isready" -> do putStrLn "readyok" 'p' : 'o' : 's' : 'i' : 't' : 'i' : 'o' : 'n' : ' ' : _ -> do putStrLn "" "usi" -> do putStrLn "usiok" -- "usinewgame" -> putStr "" _ -> putStr "" -- 何もしないという処理が書けないので、何か出力する -- loop line usi line </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ じゃあこうだ」</p> <h1 id="プロジェクトの実行ファイル、どうやって作る?"><a href="#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E5%AE%9F%E8%A1%8C%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%80%81%E3%81%A9%E3%81%86%E3%82%84%E3%81%A3%E3%81%A6%E4%BD%9C%E3%82%8B%EF%BC%9F">プロジェクトの実行ファイル、どうやって作る?</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 GHC では 実行ファイル作れたが、<br /> プロジェクトの場合は どうやる?」</p> <pre><code class="bash">muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu/shogi-project/dist-newstyle/build/x86_64-linux/ghc-9.4.7/shogi-project-0.1.0.0/x/shogi-project/build/shogi-project$ ./shogi-project </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ すごい長いファイルパスの下に 実行ファイルがあった」</p> <h1 id="将棋所がエンジン読み込まねー"><a href="#%E5%B0%86%E6%A3%8B%E6%89%80%E3%81%8C%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BE%E3%81%AD%E3%83%BC">将棋所がエンジン読み込まねー</a></h1> <pre><code class="bash">muzudho@muzudho-MS-7B09:~/Documents/Shogidokoro/Engine$ ./Lesserkai.exe Cannot open assembly './Lesserkai.exe': File does not contain a valid CIL image. </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ れさかい は C# で書いてんのか? <code>.NET Core</code> をインストールしてみるか」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/62225900/mono-app-exe-gives-error-file-does-not-contain-a-valid-cil-image">"mono app.exe" gives error "File does not contain a valid CIL image."</a></p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://dotnet.microsoft.com/en-us/download">Download .NET For Linux</a></p> <h1 id="将棋所がダメなら Shogi GUI だ"><a href="#%E5%B0%86%E6%A3%8B%E6%89%80%E3%81%8C%E3%83%80%E3%83%A1%E3%81%AA%E3%82%89+Shogi+GUI+%E3%81%A0">将棋所がダメなら Shogi GUI だ</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://mikunimaru.hatenablog.jp/entry/2018/02/23/013318">Shogi GUI</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 さらば 将棋所。 Shogi GUI へ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ダメだ Shogi GUI は文字化けしてる」</p> <h1 id="(📅 2023-12-25 ⏰ 18:59) 将棋所の再設定"><a href="#%28%F0%9F%93%85+2023-12-25+%E2%8F%B0+18%3A59%29+%E5%B0%86%E6%A3%8B%E6%89%80%E3%81%AE%E5%86%8D%E8%A8%AD%E5%AE%9A">(📅 2023-12-25 ⏰ 18:59) 将棋所の再設定</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="http://shogidokoro.starfree.jp/ubuntu.html">Ubuntu Linuxで動作させる場合の注意点</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 設定の見直し」</p> <pre><code class="bash">sudo apt install mono-complete </code></pre> <p>Output:</p> <pre><code class="bash">Reading package lists... Done Building dependency tree... Done Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: mono-complete : Depends: mono-runtime (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed Depends: mono-runtime-sgen (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed Depends: mono-llvm-support (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed Depends: libmono-2.0-1 (= 6.12.0.200-0xamarin2+ubuntu1604b1) but it is not going to be installed Depends: mono-utils (= 6.12.0.200-0xamarin2+ubuntu1604b1) but it is not going to be installed Depends: mono-devel (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed Depends: mono-mcs (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed Depends: mono-roslyn (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed Depends: mono-csharp-shell (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed Depends: mono-4.0-gac (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed Depends: libmono-cil-dev (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed Depends: ca-certificates-mono (= 6.12.0.200-0xamarin2+ubuntu1604b1) but 6.12.0.200-0xamarin2+ubuntu2004b1 is to be installed E: Unable to correct problems, you have held broken packages. </code></pre> <pre><code class="bash">sudo apt remove mono-complete </code></pre> <p>Output:</p> <pre><code class="bash">Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'mono-complete' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded. </code></pre> <pre><code class="bash">muzudho@muzudho-MS-7B09:~$ sudo apt remove mono Reading package lists... Done Building dependency tree... Done Reading state information... Done E: Unable to locate package mono </code></pre> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://askubuntu.com/questions/644938/how-to-completely-remove-mono">How to Completely remove mono?</a></p> <pre><code class="bash">sudo apt remove --purge --auto-remove mono-runtime </code></pre> <pre><code class="bash">sudo apt remove mono-complete </code></pre> <p>Output:</p> <pre><code class="plaintext">Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'mono-complete' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded. </code></pre> <pre><code class="bash">muzudho@muzudho-MS-7B09:~/Documents/Shogidokoro$ mono Shogidokoro.exe Command 'mono' not found, but can be installed with: sudo apt install mono-runtime </code></pre> <pre><code class="bash">muzudho@muzudho-MS-7B09:~$ sudo apt install mono-complete Reading package lists... Done Building dependency tree... Done Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: libgdiplus : Depends: libpng12-0 (>= 1.2.13-4) but it is not installable E: Unable to correct problems, you have held broken packages. </code></pre> <pre><code class="plaintext">libgdiplus : Depends: libpng12-0 (>= 1.2.13-4) but it is not installable </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ なんか 足りてネーの?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.mono-project.com/download/stable/#download-lin-ubuntu">moon / Downloads</a></p> <pre><code>sudo apt install ca-certificates gnupg sudo gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/mono-official-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF echo "deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list sudo apt update </code></pre> <pre><code class="bash">sudo apt install mono-devel </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ mono はインストールできたが」</p> <pre><code class="bash">sudo apt install mono-complete </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 今度はエラーは無かった」</p> <pre><code class="bash">muzudho@muzudho-MS-7B09:~/Documents/Shogidokoro$ mono Shogidokoro.exe Gtk-Message: 19:50:18.028: Failed to load module "canberra-gtk-module" </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 今度は mono コマンドで将棋所が起動した」</p> <pre><code class="bash">sudo apt install 'fonts-takao-*' </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ takao フォントを入れる」</p> <pre><code class="bash">export TERM=xterm </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 将棋エンジンを読み込む前に この設定をしておくといいらしいが、効果なし」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://qiita.com/MuAuan/items/29811d90704e965e0a35">【Jetson_nano】将棋所で将棋AIで遊ぶ♬</a></p> <pre><code class="bash">export TERM=xterm mono Shogidokoro.exe </code></pre> <p>Output:</p> <pre><code class="plaintext">Gtk-Message: 19:57:43.757: Failed to load module "canberra-gtk-module" </code></pre> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://askubuntu.com/questions/342202/failed-to-load-module-canberra-gtk-module-but-already-installed">Failed to load module “canberra-gtk-module” .... but already installed</a></p> <pre><code class="bash">sudo apt install libcanberra-gtk-module libcanberra-gtk3-module </code></pre> <pre><code class="bash">export TERM=xterm mono Shogidokoro.exe </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ これでエラーなく将棋どころが起動した」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 れさかい も きふわらべも、動かない」</p> <h2 id="ハスケルが &quot;Up to date&quot; とエコーするのを止めさせられないか?"><a href="#%E3%83%8F%E3%82%B9%E3%82%B1%E3%83%AB%E3%81%8C+%26quot%3BUp+to+date%26quot%3B+%E3%81%A8%E3%82%A8%E3%82%B3%E3%83%BC%E3%81%99%E3%82%8B%E3%81%AE%E3%82%92%E6%AD%A2%E3%82%81%E3%81%95%E3%81%9B%E3%82%89%E3%82%8C%E3%81%AA%E3%81%84%E3%81%8B%EF%BC%9F">ハスケルが "Up to date" とエコーするのを止めさせられないか?</a></h2> <pre><code class="plaintext">muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu/shogi-project$ cabal run Up to date usi id name Kifuwarakell id author Muzudho usiok quit </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ハスケルが "Up to date" とエコーするのを止めさせられないか?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 <code>run</code> するから <code>Up to date</code> と鳴くんじゃないか?」</p> <pre><code class="bash">muzudho@muzudho-MS-7B09:~/Documents/git_hub/haskell-practice-on-ubuntu/shogi-project/dist-newstyle/build/x86_64-linux/ghc-9.4.7/shogi-project-0.1.0.0/x/shogi-project/build/shogi-project$ ./shogi-project usi id name Kifuwarakell id author Muzudho usiok quit </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 確かに」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 将棋所が頭に <code>./</code> を付けてコマンドを打鍵しますかね?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/29778382/cabal-doesnt-build-executable">Cabal Doesn't Build Executable</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ カバルは実行ファイルを作ってくれないようなので、スタックを調べるか」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/61956615/how-to-compile-an-executable-from-haskell-stack-build">How to compile an executable from Haskell Stack build?</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ スタックも <code>run</code> しないと 動かんらしい」</p> <h2 id="1ファイルで作成して GHC でコンパイルしたらどうか?"><a href="#1%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%A7%E4%BD%9C%E6%88%90%E3%81%97%E3%81%A6+GHC+%E3%81%A7%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%81%97%E3%81%9F%E3%82%89%E3%81%A9%E3%81%86%E3%81%8B%EF%BC%9F">1ファイルで作成して GHC でコンパイルしたらどうか?</a></h2> <pre><code class="bash"># コンパイル ghc -o kifuwarakell.exe kifuwarakell.hs # 実行 ./kifuwarakell.exe </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 頭に <code>./</code> が付いたら、将棋所は読み込めないのでは?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 じゃあ パスを通せだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 Ubuntu で、すでにパスが通っているディレクトリーはどこだぜ?」</p> <pre><code class="bash">echo $PATH </code></pre> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ↑ コマンド打ちゃいいのよ」</p> <p>Output:</p> <pre><code class="plaintext">/home/muzudho/.cabal/bin:/home/muzudho/.ghcup/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 <code>/usr/local/games</code> とかどうか?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 将棋はゲームだしな」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 権限無いのか GUI でファイル移動できね」</p> <pre><code class="bash">cd ~ bkdir bin </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ここに <code>kifuwarakell.exe</code> を置く」</p> <pre><code class="bash">muzudho@muzudho-MS-7B09:~/bin$ pwd /home/muzudho/bin </code></pre> <pre><code class="bash">export PATH="$PATH:/home/muzudho/bin" echo $PATH </code></pre> <p>Output:</p> <pre><code class="plaintext">/home/muzudho/.cabal/bin:/home/muzudho/.ghcup/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/muzudho/bin </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ これでパスは通した」</p> <pre><code class="bash">muzudho@muzudho-MS-7B09:~/bin$ kifuwarakell.exe usi id name Kifuwarakell id author Muzudho usiok quit </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ <code>Up to date</code> も出ないし、 <code>./</code> も要らないな」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 それでも 将棋どころは きふわらべ をエンジン登録しない」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 将棋所が Ubuntu に対応してないんじゃないの?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 それはそう」</p> <pre><code class="bash">export PATH="$PATH:/home/muzudho/bin" export TERM=xterm mono Shogidokoro.exe </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ どうやっても ダメらしい。 将棋所は諦めて サーバー・プログラムを書こう」</p> <h2 id="ハスケルで通信プログラムは書けるの?"><a href="#%E3%83%8F%E3%82%B9%E3%82%B1%E3%83%AB%E3%81%A7%E9%80%9A%E4%BF%A1%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AF%E6%9B%B8%E3%81%91%E3%82%8B%E3%81%AE%EF%BC%9F">ハスケルで通信プログラムは書けるの?</a></h2> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ハスケルで通信プログラムは書けるの?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 何も分からない。 間に合わなかったら 去年のきふわらべで 出ればいいだろ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ハスケルに時間 取られてるの もったいない…… C# でいいんじゃないのか?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 エコー・サーバーのサンプル・プログラム無い?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://wiki.haskell.org/Implement_a_chat_server">Implement a chat server</a></p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ↑ チャット・サーバーなら すぐ見つかったけど」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 じゃあ それを真似よう。記事を変えようぜ?」</p> <h2 id="次の関連記事"><a href="#%E6%AC%A1%E3%81%AE%E9%96%A2%E9%80%A3%E8%A8%98%E4%BA%8B">次の関連記事</a></h2> <p>📖 <a href="https://crieit.net/posts/Haskell-o-6589722bdfef6">Haskellを練習しようぜ(^o^)?<その2o0></a></p> <p>.</p> むずでょ tag:crieit.net,2005:PublicArticle/18683 2023-12-23T17:43:53+09:00 2023-12-23T17:43:53+09:00 https://crieit.net/posts/Haskell-o Haskell でコンピューター将棋を作ろうぜ(^o^)? <h1 id="前の記事"><a href="#%E5%89%8D%E3%81%AE%E8%A8%98%E4%BA%8B">前の記事</a></h1> <p>📖 <a href="https://crieit.net/posts/Haskell-Ubuntu">Haskell を Ubuntu にインストールできねーの(^〜^)?</a></p> <h1 id="情報"><a href="#%E6%83%85%E5%A0%B1">情報</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://github.com/muzudho/kifuwarabe-shogi-haskell">kifuwarabe-shogi-haskell</a></p> <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↓ コンピューター将棋では、Haskell を使ったのは、ながとダイアリーチームの Haskell将棋 というのがある」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="http://www2.computer-shogi.org/wcsc21/appeal/haskellshogi/hsShogiAppeal.htm">Haskell将棋</a></p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ホームページが リンク切れを起こしている」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 オープンソースにして どこか管理団体が維持しないと 滅びるのよ」</p> <h1 id="Step 1.0"><a href="#Step+1.0">Step 1.0</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 初手投了する将棋エンジンを作ろうぜ?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ↓ リポジトリは作っておいたぜ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://github.com/muzudho/kifuwarabe-shogi-haskell">kifuwarabe-shogi-haskell</a></p> <pre><code class="bash">gh repo clone muzudho/kifuwarabe-shogi-haskell </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ このコマンド どうやって使うんだっけ?」</p> <p>📂 <code>Home/Documents/git_hub</code></p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ↑ とりあえず ローカルの置き場を決めましょう」</p> <pre><code class="bash">cd ~/Documents/git_hub </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ターミナルで そこへ移動」</p> <pre><code class="bash">gh repo clone muzudho/kifuwarabe-shogi-haskell </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ git hub のコマンドは前回インストール済みなので、そのままコマンドを打鍵、<br /> おっ、なにかクローンされた」</p> <pre><code class="bash">code </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ あとは Visual Studio Code を使おう」</p> <pre><code class="bash">muzudho@muzudho-MS-7B09:~/Documents/git_hub/kifuwarabe-shogi-haskell$ git commit -a On branch main Your branch is up to date with 'origin/main'. Untracked files: (use "git add <file>..." to include in what will be committed) docs/ nothing added to commit but untracked files present (use "git add" to track) </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ あれ? <code>git commit -a</code> コマンドが効かね?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 <code>docs</code> フォルダーを追加したからじゃないか?」</p> <pre><code class="bash">git add docs git commit -a # ここでメッセージを保存 git push </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ おっ、いけた」</p> <p>.</p> むずでょ tag:crieit.net,2005:PublicArticle/18665 2023-11-28T21:56:53+09:00 2023-12-24T14:09:15+09:00 https://crieit.net/posts/Haskell-Ubuntu Haskell を Ubuntu にインストールできねーの(^〜^)? <h1 id="情報"><a href="#%E6%83%85%E5%A0%B1">情報</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://github.com/muzudho/haskell-practice-on-ubuntu">haskell-practice-on-ubuntu</a></p> <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 Haskel を Ubuntu にインストールできねーの?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 何度も失敗してるよな」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 また イチからトライしましょう」</p> <h1 id="(📅2023-11-28 tue) Git Hub の使い方わかんねー(^〜^)"><a href="#%28%F0%9F%93%852023-11-28+tue%29+Git+Hub+%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9%E3%82%8F%E3%81%8B%E3%82%93%E3%81%AD%E3%83%BC%EF%BC%88%EF%BC%BE%E3%80%9C%EF%BC%BE%EF%BC%89">(📅2023-11-28 tue) Git Hub の使い方わかんねー(^〜^)</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 Windows と Ubuntu で Git Hub が違う」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 CLaunch の Ubuntu 版は無いの?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 Visual Studio Code の Ubuntu 版は無いの?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ↓ うーん、そのうち 願いが叶えられそうなのは これかな?」</p> <h2 id="Visual Studio Code をインストールしようぜ(^〜^)?"><a href="#Visual+Studio+Code+%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%82%88%E3%81%86%E3%81%9C%EF%BC%88%EF%BC%BE%E3%80%9C%EF%BC%BE%EF%BC%89%EF%BC%9F">Visual Studio Code をインストールしようぜ(^〜^)?</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yoshiyasu1111/items/e21a77ed68b52cb5f7c8">UbuntuにVSCodeをインストールする3つの方法</a></p> <p>Input:</p> <pre><code class="shell">sudo snap install --classic code </code></pre> <p>Output:</p> <pre><code class="plaintext">code 1a5daa3a from Visual Studio Code (vscode✓) installed </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ インストールされたらしいけど、どうやって起動する?」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 <code>code</code> って打ちゃあ いいんじゃないの?」</p> <p>Input:</p> <pre><code class="shell">code </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ うおっ、CUI から GUI が出てきた メモ帳みたいだ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 コマンド・プロンプトと 似たようなもんなんじゃないか?」</p> <h2 id="git をインストールしようぜ(^〜^)?"><a href="#git+%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%82%88%E3%81%86%E3%81%9C%EF%BC%88%EF%BC%BE%E3%80%9C%EF%BC%BE%EF%BC%89%EF%BC%9F">git をインストールしようぜ(^〜^)?</a></h2> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 じゃあ 次、 git」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ↓ ほらよ」</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/tommy_g/items/771ac45b89b02e8a5d64">UbuntuにGitをインストールする</a></p> <p>Input:</p> <pre><code class="shell"># インストール sudo apt-get install git </code></pre> <p>Input:</p> <pre><code class="shell"># インストールできたか確認 dpkg -l git </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 バージョンは <code>1:2.34.1-1ubuntu1.10</code> って書いてあるぜ」</p> <pre><code class="shell"># git の初期設定 git config --global user.name [任意のユーザ名] git config --global user.email [任意のユーザ名] </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 覚えてねーっ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 メールアドレスは覚えてるだろ。 Git Hub を見ると お父んの名前は <code>muzudho</code> だぜ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 初期設定したぜ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ↓ あとは ここを読めだぜ」</p> <p><a target="_blank" rel="nofollow noopener" href="https://tech-blog.rakus.co.jp/entry/20200529/git">【超入門】初心者のためのGitとGitHubの使い方</a></p> <p>Input:</p> <pre><code class="shell">git config --list </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 初期設定の中身が丸見えだぜ」</p> <h2 id="Git Hub にリポジトリを作ろうぜ(^〜^)?"><a href="#Git+Hub+%E3%81%AB%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86%E3%81%9C%EF%BC%88%EF%BC%BE%E3%80%9C%EF%BC%BE%EF%BC%89%EF%BC%9F">Git Hub にリポジトリを作ろうぜ(^〜^)?</a></h2> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↓ Web ブラウザーで Git Hub を開いて リポジトリーを作っておいたぜ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://github.com/muzudho/haskell-practice-on-ubuntu">haskell-practice-on-ubuntu</a></p> <h2 id="Ubuntu にローカル・リポジトリを作ろうぜ(^〜^)?"><a href="#Ubuntu+%E3%81%AB%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%83%BB%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86%E3%81%9C%EF%BC%88%EF%BC%BE%E3%80%9C%EF%BC%BE%EF%BC%89%EF%BC%9F">Ubuntu にローカル・リポジトリを作ろうぜ(^〜^)?</a></h2> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 Ubuntu のローカルって、どこよ?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ユーザーのホームになんかないか?」</p> <p>Input:</p> <pre><code class="shell">cd ~ ll </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 いっぱいあるが、ユーザーのホームって どこよ?」</p> <pre><code class="shell">cd Documents ll </code></pre> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 GUI で見ると <code>Home/Documents</code> というところに いろいろ置くといいんじゃない?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 じゃあそこで」</p> <pre><code class="shell">mkdir git_hub cd git_hub mkdir example1 cd example1 git init </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 おっ、 <code>Home/Documents/git_hub/example1</code> フォルダーの中に .git フォルダーが作られたぜ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ローカル・リポジトリを 新規作成するのではなくて、<br /> Git Hub のリポジトリを クローンしたかったのでは?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 あっ、そうか……」</p> <h2 id="Git Hub のリポジトリをクローンしようぜ(^〜^)?"><a href="#Git+Hub+%E3%81%AE%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%82%92%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%B3%E3%81%97%E3%82%88%E3%81%86%E3%81%9C%EF%BC%88%EF%BC%BE%E3%80%9C%EF%BC%BE%EF%BC%89%EF%BC%9F">Git Hub のリポジトリをクローンしようぜ(^〜^)?</a></h2> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↓ Git Hub で こんなコマンドライン コピーしてきたけど、使えるのかな?」</p> <pre><code class="shell">gh repo clone muzudho/haskell-practice-on-ubuntu </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ <code>gh</code> なんていうコマンド無かった」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 カレントディレクトリーを <code>Home/Documents/git_hub</code> へ移動」</p> <pre><code class="shell">git clone https://github.com/muzudho/haskell-practice-on-ubuntu </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 おっ、思ってる通り クローンできたぜ」</p> <h2 id="コミットとプッシュの練習をしようぜ(^〜^)?"><a href="#%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%A8%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E3%81%AE%E7%B7%B4%E7%BF%92%E3%82%92%E3%81%97%E3%82%88%E3%81%86%E3%81%9C%EF%BC%88%EF%BC%BE%E3%80%9C%EF%BC%BE%EF%BC%89%EF%BC%9F">コミットとプッシュの練習をしようぜ(^〜^)?</a></h2> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 Git Hub へ ファイルをアップロードする練習をしなさいよ?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 <code>Home/Documents/git_hub/haskell-practice-on-ubuntu</code> へ、フォルダーやファイルを追加して」</p> <p>Input:</p> <pre><code class="plaintext">cd haskell-practice-on-ubuntu git add Docs git commit </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 なんか コメントを入れろと出てきたが 無視したった」</p> <p>Input:</p> <pre><code class="plaintext">git push origin </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ユーザー名と パスワードを入れろと 出てきたな、忘れたな」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 思い出せだぜ!」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ダメだ 認証に失敗する」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ↓ パスワード入力による認証は 削除されたそうよ」</p> <p><a target="_blank" rel="nofollow noopener" href="https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls">HTTPS URL を使用したクローン作成</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 文章を読んだだけで 難しそうだ」</p> <h2 id="Git Hub CLI をインストールしてみようぜ(^〜^)?"><a href="#Git+Hub+CLI+%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86%E3%81%9C%EF%BC%88%EF%BC%BE%E3%80%9C%EF%BC%BE%EF%BC%89%EF%BC%9F">Git Hub CLI をインストールしてみようぜ(^〜^)?</a></h2> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↓ なんだか分からないが Git Hub CLI をインストールしてみよう」</p> <p><a target="_blank" rel="nofollow noopener" href="https://docs.github.com/en/github-cli/github-cli/about-github-cli">About GitHub CLI</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 Ubuntu って、 Debian ?」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 Ubuntu は Debian ねえ」</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/cli/cli/blob/trunk/docs/install_linux.md">Installing gh on Linux and BSD</a></p> <p>Input:</p> <pre><code class="shell">type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y) curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ && sudo apt update \ && sudo apt install gh -y </code></pre> <p>Input:</p> <pre><code class="shell">sudo apt update </code></pre> <p>Input:</p> <pre><code class="shell">sudo apt install gh </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 手順は 踏んだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 <code>gh</code> をインストールしたところで push できないぜ」</p> <pre><code class="shell">gh auth login </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 認証トークンを貼れ、とか出てくるが、なんのことだか」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 逆だ、コマンドラインからウェブ・ブラウザを開いて こっちから 認証コードを打ち込みに行くんだ。認証できた」</p> <p>Input:</p> <pre><code class="shell">git push </code></pre> <p>Output:</p> <pre><code class="plaintext">Everything up-to-date </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 別に何も起こってない」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 <code>git commit</code> 、 nano エディターの使い方が分からんな。コメント入れて保存して」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 <code>git push</code> 、これでどうか?」</p> <h2 id="よく使うコマンド"><a href="#%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89">よく使うコマンド</a></h2> <pre><code class="bash">#cd レポジトリのディレクトリ git commit -a </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ <code>git commit -a</code> で ローカルのリポジトリに ぶち込むらしい」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ なんか コメントを打鍵して <code>[Ctrl] + [O]</code> キーで <code>COMMIT_EDITMSG</code> ファイルを保存、<br /> <code>[Ctrl] + [X]</code> キーでエディターを終了」</p> <pre><code class="bash">git push </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ <code>git push</code> で リモートのリポジトリに ぶち上げるらしい」</p> <h1 id="(📅 2023-12-20 ⏰ 19:18) まだ Haskell をインストールできていない"><a href="#%28%F0%9F%93%85+2023-12-20+%E2%8F%B0+19%3A18%29+%E3%81%BE%E3%81%A0+Haskell+%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A7%E3%81%8D%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84">(📅 2023-12-20 ⏰ 19:18) まだ Haskell をインストールできていない</a></h1> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 長いなあ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://marketplace.visualstudio.com/items?itemName=haskell.haskell">VS Code Haskell Extension</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ Visual Studio Code に Haskell の拡張があるらしいんで、それを探してみるか」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.haskell.org/ghcup/">GHCup</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ さらに <code>GHCup</code> の説明を読めとあるぜ」</p> <pre><code class="bash">curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ さらに コマンドを叩けということらしい」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↓ イエスと答え続けていくと コマンドを打てと出てきた」</p> <pre><code class="bash">System requirements Please ensure the following distro packages are installed before continuing (you can exit ghcup and return at any time): build-essential curl libffi-dev libffi8ubuntu1 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5 </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ エンターキーを押したら処理が進んでるぜ」</p> <pre><code class="bash">=============================================================================== OK! /home/muzudho/.bashrc has been modified. Restart your terminal for the changes to take effect, or type "source /home/muzudho/.ghcup/env" to apply them in your current terminal session. =============================================================================== All done! To start a simple repl, run: ghci To start a new haskell project in the current directory, run: cabal init --interactive To install other GHC versions and tools, run: ghcup tui If you are new to Haskell, check out https://www.haskell.org/ghcup/steps/ </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ どうなった?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.haskell.org/ghcup/steps/">https://www.haskell.org/ghcup/steps/</a></p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ↑ URL を開いたらいいんじゃない?」</p> <pre><code class="bash">ghc --version Command 'ghc' not found, but can be installed with: sudo apt install ghc </code></pre> <pre><code class="bash">ghci --version Command 'ghci' not found, but can be installed with: sudo apt install ghc </code></pre> <pre><code class="bash">ghci Command 'ghci' not found, but can be installed with: sudo apt install ghc </code></pre> <pre><code class="bash">sudo apt install ghc </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ GHC がまだインストールされてなかった?」</p> <pre><code class="bash">ghc --version The Glorious Glasgow Haskell Compilation System, version 8.8.4 </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ このハスケルが新しいか、ネットで調べるか」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://wiki.haskell.org/Haskell">https://wiki.haskell.org/Haskell</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 9.4.8 にアップデートするには どうすればいい?」</p> <pre><code class="bash">curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 分からんから もう1回コマンドを叩いて アペンドする」</p> <pre><code class="bash">ghci GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help Prelude> </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ダメだ 古いやつが入ってしまう」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.haskell.org/ghc/blog/20231009-ghc-9.8.1-released.html">https://www.haskell.org/ghc/blog/20231009-ghc-9.8.1-released.html</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ こいつを どうやってインストールするか 調べてみるか」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 分からん」</p> <pre><code class="haskell">ghci GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help Prelude> main = putStrLn "Hello, Haskell!" Prelude> Prelude> main Hello, Haskell! Prelude> </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 自分が何をやっているのか分からん」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.haskell.org/ghcup/steps/">https://www.haskell.org/ghcup/steps/</a></p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ハスケルのファイル名は <code>hello.hs</code> みたいに名付けるそうよ」</p> <p>🗒 <code>hello.hs</code> :</p> <pre><code class="hs">main = putStrLn "Hello, Haskell!" </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ テキストファイルは こんなんでいいのかだぜ?」</p> <pre><code class="bash">ghc hello.hs </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ コンパイルが必要なようだぜ。 <code>hello</code>, <code>hello.hi</code>, <code>hello.o</code> ファイルが生成されたぜ」</p> <pre><code class="bash">./hello Hello, Haskell! </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ <code>hello</code> コマンドができたのかだぜ? あっ、動いた」</p> <h2 id="ハスケルの構文とか何も分からん"><a href="#%E3%83%8F%E3%82%B9%E3%82%B1%E3%83%AB%E3%81%AE%E6%A7%8B%E6%96%87%E3%81%A8%E3%81%8B%E4%BD%95%E3%82%82%E5%88%86%E3%81%8B%E3%82%89%E3%82%93">ハスケルの構文とか何も分からん</a></h2> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 <code>ghci</code> がインタープリター・モードになってんじゃないの? それで練習するんじゃないの?」</p> <pre><code class="ghci">ghci GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help Prelude> 1 + 1 2 Prelude> putStrLn "Hello, world!" Hello, world! </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ そのようだなあ」</p> <pre><code class="hs">Prelude> double x = x + x Prelude> double 2 4 </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 数を2倍にする double 関数を作って 実行したようだぜ、飽きてきた」</p> <pre><code class="hs">Prelude> :{ Prelude| map f list = Prelude| case list of Prelude| [] -> [] Prelude| x : xs -> f x : map f xs Prelude| :} Prelude> Prelude> Prelude> </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ どうやって このモードから抜ける?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://qiita.com/Izawa_/items/6fc0a7583dc71be48c2a">GHCiの基本的な使い方まとめ</a></p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 <code>:q</code> じゃないの?」</p> <pre><code class="hs">Prelude> :q Leaving GHCi. </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 確かに」</p> <pre><code class="hs">Prelude> :{ Prelude| map f list = Prelude| case list of Prelude| [] -> [] Prelude| x : xs -> f x : map f xs Prelude| :} Prelude> map <interactive>:7:1: error: • No instance for (Show ((t0 -> a0) -> [t0] -> [a0])) arising from a use of ‘print’ (maybe you haven't applied a function to enough arguments?) • In a stmt of an interactive GHCi command: print it Prelude> map (+1) [1, 2, 3] [2,3,4] </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 抜けたらダメだった 続けるのだった」</p> <pre><code class="hs">Prelude> :load hello.hs [1 of 1] Compiling Main ( hello.hs, interpreted ) Ok, one module loaded. *Main> main Hello, Haskell! </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ファイルの読み込み」</p> <pre><code class="hs">*Main> import Data.Bits *Main Data.Bits> shiftL 32 1 64 *Main Data.Bits> clearBit 33 0 32 </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ モジュールをインポートして論理左シフトか?」</p> <pre><code class="hs">:type putStrLn putStrLn :: String -> IO () </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 型のヘルプでも見てんのか?」</p> <pre><code class="hs">:quit Leaving GHCi. </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 終了」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 練習が全然足りないな」</p> <h1 id="キャベルもスタックも無い"><a href="#%E3%82%AD%E3%83%A3%E3%83%99%E3%83%AB%E3%82%82%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E3%82%82%E7%84%A1%E3%81%84">キャベルもスタックも無い</a></h1> <pre><code class="shell">cabal repl --build-depends async,say Command 'cabal' not found, but can be installed with: sudo apt install cabal-install stack exec --package async --package say -- ghci Command 'stack' not found, but can be installed with: sudo apt install haskell-stack </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ キャベルもスタックも無いが?」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 Visual Studio の拡張ですからねえ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.haskell.org/ghcup/install/">https://www.haskell.org/ghcup/install/</a></p> <p>📺 <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=bB4fmQiUYPw">https://www.youtube.com/watch?v=bB4fmQiUYPw</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 動画もあるが Windows で参考にならねー。飽きてきた」</p> <pre><code class="bash">curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh </code></pre> <pre><code class="bash">[ Warn ] [GHCup-00110] ghc-9.4.7 is already installed; if you really want to reinstall it, you may want to run 'ghcup install ghc --force 9.4.7' [ Info ] GHC 9.4.7 successfully set as default version [ Warn ] [GHCup-00110] cabal-3.6.2.0-p1 is already installed; if you really want to reinstall it, you may want to run 'ghcup install cabal --force 3.6.2.0-p1' </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ cabel はインストールされてるらしいが、コマンドは無い」</p> <pre><code class="bash">ghcup install cabal --force 3.6.2.0-p1 ghcup: command not found </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ <code>ghcup</code> コマンドも無いぜ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 <strong>Visual Studio Code を再起動</strong> してみては?」</p> <pre><code class="bash">ghcup --version The GHCup Haskell installer, version 0.1.20.0 </code></pre> <pre><code class="bash">ghc --version The Glorious Glasgow Haskell Compilation System, version 9.4.7 </code></pre> <pre><code class="bash">ghci --version The Glorious Glasgow Haskell Compilation System, version 9.4.7 </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ インストールされてる……」</p> <pre><code class="bash">cabal repl --build-depends async,say </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 何をやってるか分からないが コマンドを叩くぜ」</p> <pre><code class="bash">Resolving dependencies... Build profile: -w ghc-9.4.7 -O1 In order, the following will be built (use -v for more details): - hashable-1.4.3.0 (lib) (requires download & build) - say-0.1.0.1 (lib) (requires download & build) - async-2.2.5 (lib) (requires download & build) - fake-package-0 (lib) (first run) Downloading hashable-1.4.3.0 Downloaded hashable-1.4.3.0 Downloading async-2.2.5 Starting hashable-1.4.3.0 (lib) Building hashable-1.4.3.0 (lib) Downloaded async-2.2.5 Downloading say-0.1.0.1 Downloaded say-0.1.0.1 Starting say-0.1.0.1 (lib) Building say-0.1.0.1 (lib) Installing hashable-1.4.3.0 (lib) Installing say-0.1.0.1 (lib) Completed hashable-1.4.3.0 (lib) Starting async-2.2.5 (lib) Completed say-0.1.0.1 (lib) Building async-2.2.5 (lib) Installing async-2.2.5 (lib) Completed async-2.2.5 (lib) Configuring library for fake-package-0.. Preprocessing library for fake-package-0.. Warning: No exposed modules GHCi, version 9.4.7: https://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /tmp/cabal-repl.-149129/setcwd.ghci ghci> </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 何のこっちゃ」</p> <pre><code class="hs">ghci> import Control.Concurrent.Async ghci> import Say ghci> concurrently_ (sayString "Hello") (sayString "World") Hello World </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 並行処理をしたんかな?」</p> <pre><code class="bash">:quit Leaving GHCi. </code></pre> <pre><code class="bash">cabal install --lib async say --package-env . </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ 何をやってるか分からないが コマンドを叩くぜ」</p> <pre><code class="bash">Warning: Unknown/unsupported 'ghc' version detected (Cabal 3.6.2.0 supports 'ghc' version < 9.4): /home/muzudho/.ghcup/bin/ghc is version 9.4.7 Warning: Unknown/unsupported 'ghc' version detected (Cabal 3.6.2.0 supports 'ghc' version < 9.4): /home/muzudho/.ghcup/bin/ghc is version 9.4.7 Resolving dependencies... Up to date </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ だんだん 嫌になってきた」</p> <h1 id="パッケージを作る?"><a href="#%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%92%E4%BD%9C%E3%82%8B%EF%BC%9F">パッケージを作る?</a></h1> <pre><code class="bash">mkdir haskell-project cd haskell-project cabal init --interactive </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ わけもわからず打鍵」</p> <pre><code class="bash">Should I generate a simple project with sensible defaults? [default: y] Guessing dependencies... Generating LICENSE... Warning: unknown license type, you must put a copy in LICENSE yourself. Generating CHANGELOG.md... Generating src/MyLib.hs... Generating app/Main.hs... Generating haskell-project.cabal... Warning: no synopsis given. You should edit the .cabal file and add one. You may want to edit the .cabal file and add a Description field. </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ なんのこっちゃ」</p> <p>Input:</p> <pre><code class="bash">cabal build </code></pre> <p>Output:</p> <pre><code class="bash">Warning: Unknown/unsupported 'ghc' version detected (Cabal 3.6.2.0 supports 'ghc' version < 9.4): /home/muzudho/.ghcup/bin/ghc is version 9.4.7 Resolving dependencies... Build profile: -w ghc-9.4.7 -O1 In order, the following will be built (use -v for more details): - haskell-project-0.1.0.0 (lib) (first run) - haskell-project-0.1.0.0 (exe:haskell-project) (first run) Configuring library for haskell-project-0.1.0.0.. Preprocessing library for haskell-project-0.1.0.0.. Building library for haskell-project-0.1.0.0.. [1 of 1] Compiling MyLib ( src/MyLib.hs, /home/muzudho/Documents/git_hub/haskell-practice-on-ubuntu/haskell-project/dist-newstyle/build/x86_64-linux/ghc-9.4.7/haskell-project-0.1.0.0/build/MyLib.o, /home/muzudho/Documents/git_hub/haskell-practice-on-ubuntu/haskell-project/dist-newstyle/build/x86_64-linux/ghc-9.4.7/haskell-project-0.1.0.0/build/MyLib.dyn_o ) Configuring executable 'haskell-project' for haskell-project-0.1.0.0.. Preprocessing executable 'haskell-project' for haskell-project-0.1.0.0.. Building executable 'haskell-project' for haskell-project-0.1.0.0.. [1 of 1] Compiling Main ( app/Main.hs, /home/muzudho/Documents/git_hub/haskell-practice-on-ubuntu/haskell-project/dist-newstyle/build/x86_64-linux/ghc-9.4.7/haskell-project-0.1.0.0/x/haskell-project/build/haskell-project/haskell-project-tmp/Main.o ) [2 of 2] Linking /home/muzudho/Documents/git_hub/haskell-practice-on-ubuntu/haskell-project/dist-newstyle/build/x86_64-linux/ghc-9.4.7/haskell-project-0.1.0.0/x/haskell-project/build/haskell-project/haskell-project </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ なんのこっちゃ」</p> <p>Input:</p> <pre><code class="bash">cabal run </code></pre> <p>output:</p> <pre><code class="plaintext">Up to date Hello, Haskell! someFunc </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ なんのこっちゃ」</p> <h1 id="依存性の追加"><a href="#%E4%BE%9D%E5%AD%98%E6%80%A7%E3%81%AE%E8%BF%BD%E5%8A%A0">依存性の追加</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 <code>haskell-project.cabal</code> ファイルを Visual Studio Code で開くぜ」</p> <p>🗒 <code>haskell-project.cabal</code>:</p> <pre><code class="cabal">cabal-version: 2.4 name: haskell-project version: 0.1.0.0 -- A short (one-line) description of the package. -- synopsis: -- A longer description of the package. -- description: -- A URL where users can report bugs. -- bug-reports: -- The license under which the package is released. -- license: author: muzudho maintainer: [email protected] -- A copyright notice. -- copyright: -- category: extra-source-files: CHANGELOG.md library exposed-modules: MyLib -- Modules included in this library but not exported. -- other-modules: -- LANGUAGE extensions used by modules in this package. -- other-extensions: build-depends: base ^>=4.17.2.0 hs-source-dirs: src default-language: Haskell2010 executable haskell-project main-is: Main.hs -- Modules included in this executable, other than Main. -- other-modules: -- LANGUAGE extensions used by modules in this package. -- other-extensions: build-depends: base ^>=4.17.2.0, haskell-project hs-source-dirs: app default-language: Haskell2010 </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ なんのこっちゃ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 <code>src/MyLib.hs</code> ファイルを Visual Studio Code で開くぜ」</p> <p>🗒 <code>src/MyLib.hs</code> :</p> <pre><code class="hs">module MyLib (someFunc) where import System.Directory someFunc :: IO () someFunc = do contents <- listDirectory "src" putStrLn (show contents) </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ なんのこっちゃ」</p> <h2 id="モジュールの追加"><a href="#%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%AE%E8%BF%BD%E5%8A%A0">モジュールの追加</a></h2> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 以下のファイルを新規作成しろとのことだぜ」</p> <p>🗒 <code>src/OtherLib.hs</code> :</p> <pre><code class="hs">module OtherLib where otherFunc :: String -> Int otherFunc str = length str </code></pre> <pre><code class="bash">cabal repl ghci> import OtherLib <no location info>: error: Could not find module ‘OtherLib’ It is not a module in the current program, or in any known package.``` </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ ダメだ エラーだ 終わった」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 何やってんの?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 わからない。コピー貼り付けしてるだけ」</p> <p>🗒 <code>haskell-project.cabal</code>:</p> <pre><code class="cabal">library exposed-modules: MyLib </code></pre> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ↑ この部分を」</p> <p>🗒 <code>haskell-project.cabal</code>:</p> <pre><code class="cabal">library exposed-modules: MyLib OtherLib </code></pre> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 ↑ こう書き換えたらいいんじゃない?」</p> <pre><code class="bash">cabal repl Resolving dependencies... Build profile: -w ghc-9.4.7 -O1 In order, the following will be built (use -v for more details): - haskell-project-0.1.0.0 (lib) (configuration changed) Configuring library for haskell-project-0.1.0.0.. Preprocessing library for haskell-project-0.1.0.0.. GHCi, version 9.4.7: https://www.haskell.org/ghc/ :? for help [1 of 2] Compiling MyLib ( src/MyLib.hs, interpreted ) [2 of 2] Compiling OtherLib ( src/OtherLib.hs, interpreted ) Ok, two modules loaded. ghci> import OtherLib ghci> otherFunc "Hello Haskell" 13 </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↑ なんか動いた。何をやってるか分からないぜ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 エグザンプルは ここで終わってるぜ。あとは勝手に調べろとのことだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 サンプル・プログラムを探そうぜ?」</p> <h1 id="(📅 2023-12-23 sat) サンプル・プログラムを探そうぜ?"><a href="#%28%F0%9F%93%85+2023-12-23+sat%29+%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%83%BB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E6%8E%A2%E3%81%9D%E3%81%86%E3%81%9C%EF%BC%9F">(📅 2023-12-23 sat) サンプル・プログラムを探そうぜ?</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ↓ ハスケルの素人はこれを観ろ、ということだぜ」</p> <ul> <li>📖 <a target="_blank" rel="nofollow noopener" href="https://github.com/haskell-beginners-2022/course-plan">https://github.com/haskell-beginners-2022/course-plan</a> <ul> <li>📺 <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=6MsQcUprO9o&list=PLOJjn67NeYg9cWA4hyIWcxfaeX64pwo1c">Haskell Beginners 2022: Lecture 1</a> - 1時間23分</li> </ul></li> </ul> <h2 id="FP - Functional Programming"><a href="#FP+-+Functional+Programming">FP - Functional Programming</a></h2> <pre><code>fx(x) = x^2 </code></pre> <p>プログラミングの関数は、この数学の関数ではない</p> <ul> <li>無限ループでハングするから</li> <li>副作用があるから</li> <li>例外があるから</li> <li>メモリがなくなるから</li> </ul> <p>プログラミングの関数は</p> <ul> <li><p>ブロックを組み立てるようなもの</p> <ul> <li>Define</li> <li>Call</li> <li>Compose</li> <li>Pass as an argument</li> <li>Inspect</li> </ul></li> <li><p>FP Concepts</p> <ul> <li>Higher-Order Functions (HOF)</li> <li>Algebraic Data Types (ADT)</li> <li>Pattern Matching</li> <li>Purity</li> <li>Immutability</li> <li>Totality</li> <li>Laziness</li> </ul></li> <li><p>Haskell Features</p> <ul> <li>Static typing</li> <li>Polymorphisms</li> <li>Type inference</li> <li>Layout-sensitivity</li> <li>ML syntax</li> <li>Automatic currying</li> <li>Garbabe collector</li> <li>Green threads</li> <li>Software Transactional memory (STM)</li> <li>etc...</li> </ul></li> <li><p>Haskell Toolchain</p> <ul> <li>GHC (Glasgow Haskell Compiler) - the compiler</li> <li>GHCi (GHC interactive) - interactive interpreter aka REPL(Read-Eval-Print-Loop)</li> <li>cabal - a Haskell build tool, the .......</li> <li>stack</li> <li>HLS (Haskell Language Server)</li> <li>ghcup</li> </ul></li> <li><p>Haskell Toolchain / GHCi</p> <ul> <li>Arithmetic</li> <li>Logic</li> <li>Calling functions <ul> <li><code>()</code> are important!</li> </ul></li> <li>Types - 式は型を持つ。 <code>:t</code> や <code>:tpye</code> で型を見れる。 型の型は見れない</li> <li>Types of numbers - <code>:t +d</code> で調べる</li> <li><p>Types of functions -> <code>:t div</code> より、 <code>:t +d div</code> を使って調べる。2項の引数のとき、見やすい</p></li> <li><p>List</p> <ul> <li>List literals - <code>[]</code> の話。 <code>[] ++ []</code> とか</li> <li>List: head/tail/last/init <ul> <li>空リストの head は例外</li> </ul></li> <li>List: more functions <ul> <li>reverse</li> <li>take</li> <li>drop</li> <li>null</li> <li>elem</li> <li>concat</li> <li>length</li> <li><code>!!</code> - この操作は処理が遅い。インデックスを使ったランダムアクセスか?</li> </ul></li> <li>List: ranges <ul> <li><code>[1 .. 10]</code> や、 <code>[1, 3 .. 20]</code></li> <li><code>[10 .. 1]</code> は空っぽ。 <code>[10, 9 .. 1]</code> はできる</li> <li><code>[0 .. ]</code> インフィニティもできる</li> </ul></li> </ul></li> </ul></li> <li><p>Lazy evaluation</p> <ul> <li><code>take 3 [0 .. ]</code> で、 <code>[0, 1, 2]</code></li> <li><code>take 3 (drop 5 [0 .. ]</code> で、<code>[5,6,7]</code></li> <li><code>length [0 .. ]</code> - 終わらない。無限のリストには注意</li> </ul></li> <li><p>ディスプレイの信号が消えた</p></li> <li><p>Syntax</p> <ul> <li>Define a function</li> <li>Loading a module</li> </ul></li> <li><p>Packages</p> <ul> <li>module</li> <li>package</li> <li>Hackage</li> <li>base</li> <li>prelude</li> </ul></li> <li><p>if-then-else</p> <ul> <li><code>def list = if null list then def else head list</code></li> </ul></li> </ul> <pre><code class="hs">headOfDefault def list = if null list then def else head list </code></pre> <ul> <li>続き <ul> <li>guards - マッチ構文みたいなやつ</li> </ul></li> </ul> <pre><code>sign n | 略 </code></pre> <ul> <li><p>続き</p> <ul> <li><code>let-in</code> - リストに含まれているか調べる?</li> <li><code>where</code> - 関数定義で使う?</li> <li><code>immutablirity</code> - 1回だけ代入できるというもの</li> <li>How do you change if you can't? <ul> <li>Recursion</li> <li>No more loops</li> </ul></li> </ul></li> <li><p>Higher-order functions</p> <ul> <li>First-Class Functions</li> <li>Lambda functions</li> <li>Partial application</li> <li>Standard HOFs <ul> <li>map</li> <li>filter even</li> <li>filter</li> <li>any</li> <li>concatMap replicate</li> <li>take iterate</li> </ul></li> <li>Functions inside lists</li> <li>Recap: GHCi commands <ul> <li><code>:q</code></li> <li><code>:t</code></li> <li><code>:t +d</code></li> <li><code>:l</code></li> <li><code>:i</code></li> </ul></li> <li>More sources</li> </ul></li> </ul> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 フーム」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 ↓ 基礎勉強は もういいだろ、コンピューター将棋を作ろうぜ?」</p> <p>📖 <a href="https://crieit.net/posts/Haskell-o">Haskell でコンピューター将棋を作ろうぜ(^o^)?</a></p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 レクチャーの動画は あと3本 あるみたいよ?</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 基礎勉強ばっかりだと飽きるんで 並行してやろう」</p> <h1 id="レクチャー2"><a href="#%E3%83%AC%E3%82%AF%E3%83%81%E3%83%A3%E3%83%BC%EF%BC%92">レクチャー2</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 すぐ 詰まる。動画見よ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=rf-lie7U04Q">Haskell Beginners 2022: Lecture 2</a></p> <ul> <li>Pattern Matching <ul> <li>Pattern</li> <li><code>case-of</code> - スイッチ文みたいなやつか?</li> </ul></li> </ul> <pre><code class="hs">eval :: Char -> Int -> Int -> Int eval op x y = case op of '+' -> x + y '-' -> x - y '*' -> x * y '/' -> div x y _ -> 0 </code></pre> <ul> <li><p>続き</p> <ul> <li>Patterns on lists</li> <li>Structural List Patterns</li> <li>Heads or Tails?</li> <li>List Recursion</li> <li><code>What's wrong, Haskell?</code> - 書き方でコンパイル・エラーが出る例、エラーは出ないが悪い書き方の例</li> <li><code>Totality</code> - すべての入力に対して出力が定義されていることか? <ul> <li><code>Partial</code> - 非 total</li> </ul></li> </ul></li> <li><p>Data</p> <ul> <li>Tuples</li> <li>Working with tuples</li> <li>Algebraic Data Type (ADT) <ul> <li><code>Product Type</code> - 異なる型などを結合したもの <ul> <li><code>data: Product</code></li> <li><code>data: Working with data</code> - セッターとゲッターの書き方</li> <li><code>data: Records</code> - 構造体みたいなもん</li> </ul></li> <li><code>Sum Type</code> <ul> <li><code>Sum Types: Enumerations</code> - いわゆる列挙型</li> <li><code>Sum Types</code> - Result とか</li> <li><code>Recursive data types</code> <ul> <li><code>Empty list</code></li> <li><code>An eleement prepended to a list</code></li> </ul></li> <li><code>type</code> - type キーワード。型の別名? 式が見やすくなる</li> <li><code>newtype</code> - コンストラクタの別名??</li> </ul></li> </ul></li> </ul></li> <li>Polymorphism <ul> <li><code>Parametric polymorphism</code> - ジェネリクスみたいなやつ</li> <li><code>Real types</code></li> <li><code>Hoogle</code> - Haskell Search Engine</li> <li><code>Polymorphic types</code></li> <li><code>Common types</code> - Optional Value とか、左右とか</li> <li><code>Common Functions</code></li> </ul></li> <li>Back to Functions <ul> <li><code>Eta-reduction, part1</code></li> <li><code>Eta-reduction, part2</code></li> <li><code>Function Composition</code> <ul> <li><code>ELI5 Composition</code></li> </ul></li> <li><code>Composition + Eta-reduction</code></li> <li>More sources</li> </ul></li> </ul> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 はー、ふーん、うーん?」</p> <h1 id="レクチャー3"><a href="#%E3%83%AC%E3%82%AF%E3%83%81%E3%83%A3%E3%83%BC%EF%BC%93">レクチャー3</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=Vs-vvlYLtRI">Haskell Beginners 2022: Lecture 3</a></p> <ul> <li>Common properties</li> <li>Polimorphisms <ul> <li><code>Parametric Polymorphism</code></li> <li><code>Ad-hoc polymorphism</code></li> </ul></li> <li>class</li> <li>instance</li> <li>Separation of concerns <ul> <li>data</li> <li>class</li> <li>instance</li> </ul></li> <li>Default methods</li> <li>Not Java Interfaces</li> <li><code>{-# LANGUAGE #-}</code> - ランゲージ・プラグマ。</li> <li>Standard Typeclasses <ul> <li>Eq</li> <li><code>Ord</code> - Ordering 比較演算子 <ul> <li>LT</li> <li>EQ</li> <li>GT</li> </ul></li> <li>Show</li> <li>Read</li> <li>Bounded</li> <li>Enum</li> <li>Num</li> </ul></li> <li>Type interface <ul> <li><code>deriving</code> - 派生</li> <li>Generaliz(s)edNewtypeDeriving</li> <li>Algebra <ul> <li><code><></code> - ダイヤモンド演算子</li> </ul></li> <li>newtype again</li> </ul></li> <li>Everything is Semigroup, Okay, not really everything... <ul> <li><code>Semigroup</code></li> </ul></li> <li>Algebra, part2 <ul> <li><code>Monoid</code></li> <li>Not everything is Monoid</li> </ul></li> <li>Modules</li> <li>Kind <ul> <li>Be kind to us, Haskell <ul> <li><code>Kind</code> - a type of a type</li> <li>Kindly check your types</li> </ul></li> </ul></li> <li>typeclass for type constructors</li> <li>Functor</li> <li><code>Functor laws</code> - 10種類 <ul> <li><code>1: Identity</code></li> <li><code>2: Composition</code></li> </ul></li> <li>Folds <ul> <li><code>ステップ関数</code></li> <li>Everything is a Fold</li> <li>How foldr folds <ul> <li>コンスピレーター</li> </ul></li> <li>How foldl/foldl' folds</li> <li>foldr vs foldl</li> <li>Foldable</li> </ul></li> <li>Strict evaluation <ul> <li><code>等式推論</code></li> </ul></li> <li><code>{-# LANGUAGE BangPatterns #-}</code></li> <li>Use strict/lazy evaluation wise.....</li> <li>More sources</li> </ul> <h1 id="レクチャー4"><a href="#%E3%83%AC%E3%82%AF%E3%83%81%E3%83%A3%E3%83%BC%EF%BC%94">レクチャー4</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=12D4Y2Hdnhg">Haskell Beginners 2022: Lecture 4</a></p> <ul> <li>Monad: The Idea <ul> <li>Maybe, yes? Maybe, no? <ul> <li><code>andThen</code> - Ordinary helper function</li> <li>ワンライナーで書けるようになる</li> </ul></li> <li>Either way</li> <li>Multiple combinations</li> <li>It there a pattern?</li> <li>What to do when we see a pattern? <ul> <li><code>1. Nothing</code></li> <li><code>2. Recognize</code></li> <li><code>3. Copy-paste</code></li> <li><code>4. Abstract</code></li> <li><code>5. Put in a library</code></li> </ul></li> </ul></li> <li>Monad is a pattern <ul> <li>数学の圏論と違う。 Haskell は概念を借りてきただけ。</li> <li>Monad</li> <li><code>return</code> も関数</li> <li>Just a typeclass</li> <li>Instance</li> <li>Laws</li> </ul></li> <li>Generalizing <ul> <li><code>(:[])</code> - robot monkey operator</li> </ul></li> <li>Refactoring</li> <li>Actually, in Haskell... <ul> <li><code>pure</code> - ハスケルでは return の代わりに pure をよく使う</li> </ul></li> <li>And that's the Monad</li> <li>Real World <ul> <li><code>Purity</code> - 純粋。副作用がない関数。 <ul> <li><code>1. Determinism</code></li> <li><code>2. Easier reasoning</code></li> <li><code>3. Simpler testing</code></li> <li><code>4. Composability</code></li> <li><code>5. Optimizations</code></li> <li><code>6. Parallelism</code></li> </ul></li> <li>Purity + Laziness <ul> <li><code>getLine</code></li> </ul></li> <li>Input/Output(IO)</li> <li>Concept of IO</li> <li>How to run IO? <ul> <li><code>unit type</code> - 空の丸括弧</li> </ul></li> <li>How to run Haskell programs? <ul> <li><code>main</code> - メイン関数</li> <li>ハローワールド</li> <li>Printing twice</li> </ul></li> <li><code>do 構文</code> - do-notation <ul> <li><code>let-in rule</code></li> <li><code>Example with do</code></li> </ul></li> </ul></li> <li>Cabal - カバール <ul> <li>独自の形式。拡張子は <code>.cabal</code></li> <li><code>app</code> フォルダーと、 <code>src</code> フォルダーに分ける。 app は実行可能で、 src はライブラリーか?</li> <li>Typical main</li> <li><code>build-depends</code> <ul> <li><code>Hackage</code> - ユーザー作成のパッケージが置いてる?</li> </ul></li> </ul></li> <li><code>Functional,Imperative</code> <ul> <li><code>Imperative style</code> - 命令型スタイル</li> <li><code>Functional style</code> - 関数型スタイル</li> </ul></li> <li>More sources</li> </ul> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ふーむむむ?」</p> <h1 id="次の関連記事"><a href="#%E6%AC%A1%E3%81%AE%E9%96%A2%E9%80%A3%E8%A8%98%E4%BA%8B">次の関連記事</a></h1> <p>📖 <a href="https://crieit.net/posts/Haskell-o">Haskell でコンピューター将棋を作ろうぜ(^o^)?</a></p> <p>.</p> むずでょ tag:crieit.net,2005:PublicArticle/15437 2019-09-29T19:46:32+09:00 2019-09-29T19:46:32+09:00 https://crieit.net/posts/Data-Aeson Data.Aesonの使い方 <p><a target="_blank" rel="nofollow noopener" href="https://www.leo-leo.uno/2019/02/09/798/">自分のブログ記事</a>からのクロス投稿です。</p> <p>HaskellのJSONライブラリとしておそらくメジャーな<a target="_blank" rel="nofollow noopener" href="http://hackage.haskell.org/package/aeson">Data.Aeson</a>ですが、使い方が難しいので色々試行錯誤しています。</p> <p>以降のコードはghci上で実行することを想定しています。<br /> 適当にstackでプロジェクトを作って、aesonをcabalファイルのbuild-dependsに追加してビルドし、<code>stack ghci</code>とするのが良いと思います。あと、<a target="_blank" rel="nofollow noopener" href="http://hackage.haskell.org/package/text">Data.Text</a>や<a target="_blank" rel="nofollow noopener" href="http://hackage.haskell.org/package/unordered-containers">Data.HashMap</a>なども必要です。</p> <pre><code class="shell"># ここはターミナルで stack new sandbox-prj simple cd sandbox-prj # cabalファイルのbuild-dependsにaeson, text, unordered-containers, vectorを追記 stack build stack ghci </code></pre> <p>はじめに、以下をghci上でコピペしておいてください。以降のコードが全部動くはずです。</p> <pre><code class="haskell">-- ghci上で -- 最初にこれらをコピペしておくと、以降のコードが全部動くはず -- 後でGHC拡張を使う :set -XDeriveGeneric :set -XExistentialQuantification :set -XFlexibleContexts :set -XFlexibleInstances :set -XGADTs :set -XInstanceSigs :set -XOverloadedStrings :set -XTypeFamilies :set +m -- 後で色々使う import Control.Applicative (empty, pure) import Data.Aeson import qualified Data.Aeson.Encoding.Internal as DAE import Data.Aeson.Types import Data.Char (toLower, toUpper) import qualified Data.HashMap.Lazy as HML import qualified Data.HashMap.Strict as HMS import qualified Data.Text as T import qualified Data.Text.Lazy as TL import qualified Data.Vector as V import GHC.Generics </code></pre> <h3 id="基本的な使い方"><a href="#%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B9">基本的な使い方</a></h3> <p>基本的な型については特にパーサーを定義しなくて良いので、いきなりエンコード・デコードできます。</p> <p>エンコード</p> <pre><code class="haskell">encode 1 -- --> "1" encode "hello" -- --> "\"hello\"" encode [1,2,3] -- --> "[1,2,3]" encode (1,2) -- --> "[1,2]" encode (Just 1) -- --> "1" encode True -- --> "true" encode Null -- --> "null" encode (1234, "hello", True, False, [1,2,3], Just 10) -- --> "[1234,\"hello\",true,false,[1,2,3],10]" </code></pre> <p>デコードは、Haskellの型を指定する必要があります。</p> <pre><code class="haskell">-- 型を指定しないとデコードできない decode "1" -- --> Nothing decode "1" :: Maybe Int -- --> Just 1 decode "\"hello\"" :: Maybe String -- --> Just "hello" decode "[1234,\"hello\",true,false,[1,2,3],10]" :: Maybe (Int,String,Bool,Bool,[Int],Maybe Int) -- --> Just (1234,"hello",True,False,[1,2,3],Just 10) </code></pre> <h3 id="ToJSON, FromJSON"><a href="#ToJSON%2C+FromJSON">ToJSON, FromJSON</a></h3> <p>エンコード・デコードするためには、そのデータ型が<code>ToJSON</code>・<code>FromJSON</code>のインスタンスになっている必要があります。<br /> このように定義します。<code>DeriveGeneric</code>拡張(はじめにセットしたやつ)と<code>GHC.Generics</code>が必要です。</p> <pre><code class="haskell">data MyData = MyData { field :: String } deriving (Show, Generic) instance FromJSON MyData instance ToJSON MyData myData = MyData "my data!!" encode myData -- --> "{\"field\":\"my data!!\"}" decode "{\"field\":\"my data!!\"}" :: Maybe MyData -- --> Just (MyData {field = "my data!!"}) </code></pre> <p>簡単ですね。基本的には、エンコード・デコードの実装を自分で定義しなくても自動的に導出してくれます。</p> <pre><code class="haskell">-- :{ :} はghciで複数行定義をするときに使う記号 :{ data Person = Person { name :: String , age :: Int , group :: [String] } deriving (Show, Generic) :} instance FromJSON Person instance ToJSON Person p1 = Person "Neo" 30 ["groupA", "groupB"] p2 = Person "Morpheus" 40 ["groupA"] p3 = Person "Trinity" 30 [] encode p1 -- --> "{\"group\":[\"groupA\",\"groupB\"],\"age\":30,\"name\":\"Neo\"}" decode "{\"group\":[\"groupA\",\"groupB\"],\"age\":30,\"name\":\"Neo\"}" :: Maybe Person -- --> Just (Person {name = "Neo", age = 30, group = ["groupA","groupB"]}) -- リストはもともとToJSONとFromJSONのインスタンスなので、 encode [p1, p2, p3] -- --> "[{\"group\":[\"groupA\",\"groupB\"],\"age\":30,\"name\":\"Neo\"},{\"group\":[\"groupA\"],\"age\":40,\"name\":\"Morpheus\"},{\"group\":[],\"age\":30,\"name\":\"Trinity\"}]" decode "[{\"group\":[\"groupA\",\"groupB\"],\"age\":30,\"name\":\"Neo\"},{\"group\":[\"groupA\"],\"age\":40,\"name\":\"Morpheus\"},{\"group\":[],\"age\":30,\"name\":\"Trinity\"}]" :: Maybe [Person] -- --> Just [Person {name = "Neo", age = 30, group = ["groupA","groupB"]},Person {name = "Morpheus", age = 40, group = ["groupA"]},Person {name = "Trinity", age = 30, group = []}] </code></pre> <p>※ 彼らの年齢は間違っているかもしれません。</p> <p>Haskellのレコードを使うときは、以下のように型名のプレフィックスをフィールド名につけて定義することが多いかもしれません(あるいはlensなどを使うのかもしれませんが)。それでも、JSONのフィールド名はシンプルに"title", "created"としておきたいですよね。<br /> こういう場合、<a target="_blank" rel="nofollow noopener" href="http://hackage.haskell.org/package/aeson-1.4.2.0/docs/Data-Aeson.html#v:defaultOptions"><code>defaultOptions</code></a>というのを使います。<code>fieldLabelModifier</code>に、フィールド名の変換関数を定義しておけば、エンコード時に適用してくれます。ここでは、プレフィックス("movie"の5文字)を取り除き、かつ小文字にするというルールにしました。</p> <pre><code class="haskell">:{ data Movie = Movie { movieTitle :: String , movieCreated :: Int } deriving (Show, Generic) :} movieOptions = defaultOptions {fieldLabelModifier = map toLower . drop 5} instance ToJSON Movie where toEncoding = genericToEncoding movieOptions instance FromJSON Movie where parseJSON = genericParseJSON movieOptions movie = Movie "The Matrix" 1999 encode movie -- --> "{\"title\":\"The Matrix\",\"created\":1999}" decode "{\"title\":\"The Matrix\",\"created\":1999}" :: Maybe Movie -- --> Just (Movie {movieTitle = "The Matrix", movieCreated = 1999}) </code></pre> <h3 id="エンコーダー・デコーダーを自前で定義"><a href="#%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%80%E3%83%BC%E3%83%BB%E3%83%87%E3%82%B3%E3%83%BC%E3%83%80%E3%83%BC%E3%82%92%E8%87%AA%E5%89%8D%E3%81%A7%E5%AE%9A%E7%BE%A9">エンコーダー・デコーダーを自前で定義</a></h3> <p>では、代数データ型の場合はどうでしょうか。基本的には以下のように自動導出できます。</p> <pre><code class="haskell">data Size = Small|Medium|Large deriving (Show, Generic) instance ToJSON Size instance FromJSON Size encode [Small, Medium, Large] -- --> "[\"Small\",\"Medium\",\"Large\"]" decode "[\"Small\",\"Medium\",\"Large\"]" :: Maybe [Size] -- --> Just [Small,Medium,Large] </code></pre> <p>ただ、JSONデータではキャメルケースでなく<code>small</code>, <code>medium</code>, <code>large</code>のように小文字で表現したいかもしれません。その場合は、以下のように自分で定義する必要があります。<code>ToJSON</code>のインスタンスにするには、<code>toJSON</code>か、<code>toEncoding</code>を自分で定義します。以下のような型です。</p> <pre><code class="haskell">toJSON :: a -> Value toEncoding :: a -> Encoding </code></pre> <p><code>toJSON</code>は任意の型をData.Aesonの<code>Value</code>型にします。したがって、<code>toJSON</code>のみを定義した場合は、<code>toEncoding</code>が自動導出されます。JSONにエンコードするときは、一旦<code>Value</code>に変換され、その後JSONの文字列に変換されます。<br /> 一方、<code>toEncoding</code>を直接定義することもできて、その場合は、<code>Value</code>を経由せず直接エンコードされることになります。ここには<a target="_blank" rel="nofollow noopener" href="http://hackage.haskell.org/package/aeson-1.4.2.0/docs/Data-Aeson.html#g:7">歴史的経緯</a>があるようです。</p> <pre><code class="haskell">-- toJSONを定義する場合 data Size = Small|Medium|Large deriving (Show, Generic) instance ToJSON Size where toJSON Small = String "small" toJSON Medium = String "medium" toJSON Large = String "large" encode [Small, Medium, Large] -- --> "[\"small\",\"medium\",\"large\"]" </code></pre> <pre><code class="haskell">-- toEncodingを定義する場合 data Size = Small|Medium|Large deriving (Show, Generic) instance ToJSON Size where toEncoding Small = DAE.string "small" toEncoding Medium = DAE.string "medium" toEncoding Large = DAE.string "large" encode [Small, Medium, Large] -- --> "[\"small\",\"medium\",\"large\"]" </code></pre> <p><code>FromJSON</code>のインスタンスについては、<code>parseJSON</code>を定義します。こちらは少し面倒です。以下のような型をしています。</p> <pre><code class="haskell">parseJSON :: Value -> Parser a </code></pre> <pre><code class="haskell">-- withTextの第一引数("Size")は、どんな文字列でも良いみたい。 -- なんのための引数なのかまだわかっていない。 instance FromJSON Size where parseJSON = withText "Size" $ \t -> fromString (TL.unpack (TL.fromStrict t)) where fromString :: String -> Parser Size fromString "small" = pure Small fromString "medium" = pure Medium fromString "large" = pure Large fromString _ = empty decode "[\"small\",\"medium\",\"large\"]" :: Maybe [Size] -- --> Just [Small,Medium,Large] </code></pre> <p>これで、<code>Size</code>データを使ったレコードもエンコード・デコードすることができます。</p> <pre><code class="haskell">:{ data Tomato = Tomato { size :: Size , brand :: String } deriving (Show, Generic) :} instance ToJSON Tomato instance FromJSON Tomato mini = Tomato Small "famous brand name" encode mini -- --> "{\"size\":\"small\",\"brand\":\"famous brand name\"}" decode "{\"size\":\"small\",\"brand\":\"famous brand name\"}" -- --> Just (Tomato {size = Small, brand = "famous brand name"}) </code></pre> <h3 id="多相型"><a href="#%E5%A4%9A%E7%9B%B8%E5%9E%8B">多相型</a></h3> <p>このようなデータ型でもこれまでと同じように<code>ToJSON</code>・<code>FromJSON</code>のインスタンスにすることができます。自動導出の場合は、以下の例のようにエンコード時に<code>Wrap</code>が外れます。</p> <pre><code class="haskell">data Wrap a = Wrap a deriving (Show, Generic) instance ToJSON a => ToJSON (Wrap a) instance FromJSON a => FromJSON (Wrap a) encode $ Wrap 1 -- --> "1" encode $ Wrap "wrapped" -- --> "\"wrapped\"" decode "1" :: Maybe (Wrap Int) -- --> Just (Wrap 1) decode "\"wrapped\"" :: Maybe (Wrap String) -- --> Just (Wrap "wrapped") </code></pre> <p>今度は<code>Point a</code>型で考えます。自動導出で問題ない場合は良いのですが、自分で定義しようとした時に、少し悩みました。<code>toJSON</code>も<code>parseJSON</code>も、<code>a</code>の部分の値をエンコード・デコードする処理を自分で定義してしまうと型を決めなくてはなりません。そうすると<code>a</code>のままではできず、<code>Point Int</code>などの具体的な型で定義せざるを得ません。そこで、<code>a</code>の部分については、自分で定義せず、<code>toJSON</code>や<code>parseJSON</code>をそのまま使います。もともと<code>a</code>はそれらのインスタンスであることを仮定しているので、自分で定義する必要がありません。以下のように書くと、型引数をとる型についても定義できます。</p> <pre><code>data Point a = Point a a deriving (Show, Generic) instance ToJSON a => ToJSON (Point a) where toJSON (Point x y) = Object $ HMS.fromList [("point", toJSON [x,y])] :{ instance FromJSON a => FromJSON (Point a) where parseJSON (Object o) = case HML.lookup "point" o of Just arr -> let pts = parseJSON arr :: FromJSON b => Parser (b, b) in Point <$> (fst <$> pts) <*> (snd <$> pts) Nothing -> empty :} pi = Point 1 2 ps = Point "one" "two" encode pi -- --> "{\"point\":[1,2]}" encode ps -- --> "{\"point\":[\"one\",\"two\"]}" decode "{\"point\":[1,2]}" :: Maybe (Point Int) -- --> Just (Point 1 2) decode "{\"point\":[\"one\",\"two\"]}" :: Maybe (Point String) -- --> Just (Point "one" "two") </code></pre> <h3 id="少し複雑な代数データ型"><a href="#%E5%B0%91%E3%81%97%E8%A4%87%E9%9B%91%E3%81%AA%E4%BB%A3%E6%95%B0%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B">少し複雑な代数データ型</a></h3> <pre><code class="haskell">data Gender = Female|Male deriving (Show, Generic) data Property = Name String|Age Int|Gender Gender deriving (Show, Generic) instance ToJSON Gender instance FromJSON Gender instance ToJSON Property instance FromJSON Property props = [Name "Neo", Age 30, Gender Male] encode props -- --> "[{\"tag\":\"Name\",\"contents\":\"Neo\"},{\"tag\":\"Age\",\"contents\":30},{\"tag\":\"Gender\",\"contents\":\"Male\"}]" decode "[{\"tag\":\"Name\",\"contents\":\"Neo\"},{\"tag\":\"Age\",\"contents\":30},{\"tag\":\"Gender\",\"contents\":\"Male\"}]" :: Maybe [Property] -- --> Just [Name "Neo",Age 30,Gender Male] </code></pre> <p>このような型でもすべて自動導出できました。しかし、JSONのフォーマットは微妙ですね。以下のようになって欲しいです。(レコード型で定義すれば良いだけの話なのですが、今は例ということで。。)</p> <pre><code class="json">{ "name": "Neo", "age": 30, "gender": "male" } </code></pre> <p>自前で定義しましょう。名前を変えるため別の例にしますが、データ構造はほぼ一緒です。</p> <pre><code class="haskell">data CarType = Coupe|SUV deriving (Show, Generic) data Car = Model String|Release Int|CarType CarType deriving (Show, Generic) instance ToJSON CarType where toJSON Coupe = String "coupe" toJSON SUV = String "suv" instance FromJSON CarType where parseJSON = withText "CarType" $ \t -> fromString (T.unpack t) where fromString :: String -> Parser CarType fromString "coupe" = pure Coupe fromString "suv" = pure SUV fromString _ = empty instance ToJSON Car where toJSON (Model s) = object [("model", toJSON s)] toJSON (Release i) = object [("release", toJSON i)] toJSON (CarType c) = object [("car_type", toJSON c)] instance FromJSON Car where parseJSON (Object o) = case HML.lookup "model" o of Just (String s) -> pure (Model $ T.unpack s) _ -> case HML.lookup "release" o of Just i -> Release <$> (parseJSON i :: Parser Int) _ -> case HML.lookup "car_type" o of Just t -> CarType <$> (parseJSON t :: Parser CarType) myCar = [Model "Land Cruiser", Release 1954, CarType SUV] encode myCar -- --> "[{\"model\":\"Land Cruiser\"},{\"release\":1954},{\"car_type\":\"suv\"}]" decode "[{\"model\":\"Land Cruiser\"},{\"release\":1954},{\"car_type\":\"suv\"}]" :: Maybe [Car] -- --> Just [Model "Land Cruiser",Release 1954,CarType SUV] </code></pre> <p>これで、望みのJSON形式でエンコード・デコードできるようになりました。</p> <h3 id="Either型"><a href="#Either%E5%9E%8B">Either型</a></h3> <p><code>Either</code>型の場合はどうなるでしょうか。わからないのでまずは自動導出して見ましょう。</p> <pre><code class="haskell">:{ data Filter = Filter { value :: Either String [String] } deriving (Show, Generic) :} instance ToJSON Filter instance FromJSON Filter filterL = Filter (Left "eq") filterR = Filter (Right ["eq", "gt"]) encode filterL -- --> "{\"value\":{\"Left\":\"eq\"<span>}</span><span>}</span>" encode filterR -- --> "{\"value\":{\"Right\":[\"eq\",\"gt\"]<span>}</span><span>}</span>" decode "{\"value\":{\"Left\":\"eq\"<span>}</span><span>}</span>" :: Maybe (Filter) -- --> Just (Filter {value = Left "eq"}) decode "{\"value\":{\"Right\":[\"eq\",\"gt\"]<span>}</span><span>}</span>" :: Maybe (Filter) -- --> Just (Filter {value = Right ["eq","gt"]}) </code></pre> <p>一応できました。しかし、JSONデータの中に"Left"や"Right"が入ってしまって冗長です。この場合は、以下のようになって欲しいですね。</p> <pre><code class="json"># Leftの場合 {"value": "eq"} # Rightの場合 {"value": ["eq", "gt"]} </code></pre> <p>以下のように定義しましょう。別の例にするのが面倒なので、同じデータを再定義します。</p> <pre><code>:{ data Filter = Filter { value :: Either String [String] } deriving (Show, Generic) :} instance ToJSON Filter where toJSON (Filter (Left s)) = object [("value", toJSON s)] toJSON (Filter (Right ss)) = object [("value", toJSON ss)] -- Arrayの時に、判定できていないのが難点 -- でも、失敗した時はちゃんとNothingを返してくれるのでとりあえず良いか instance FromJSON Filter where parseJSON (Object o) = case HML.lookup "value" o of Just (String s) -> pure (Filter (Left $ T.unpack s)) Just arr -> (Filter . Right) <$> (parseJSON arr :: Parser [String]) _ -> empty filterL = Filter (Left "eq") filterR = Filter (Right ["eq", "gt"]) encode filterL -- --> "{\"value\":\"eq\"}" encode filterR -- --> "{\"value\":[\"eq\",\"gt\"]}" decode "{\"value\":\"eq\"}" :: Maybe Filter -- --> Just (Filter {value = Left "eq"}) decode "{\"value\":[\"eq\",\"gt\"]}" :: Maybe Filter -- --> Just (Filter {value = Right ["eq","gt"]}) </code></pre> <p><code>Either</code>型の場合もこのように定義することで自由にJSONとの変換ができます。ちなみに上記の例のようにではなく、<code>Either String a</code>としてエラーメッセージ付きの<code>Maybe</code>のような扱いをしたい場合は、<a target="_blank" rel="nofollow noopener" href="https://www.stackage.org/haddock/lts-13.6/aeson-1.4.2.0/Data-Aeson-Types.html#v:parseEither">専用の関数がすでに用意されている</a>ようです。</p> <h3 id="GADT"><a href="#GADT">GADT</a></h3> <p>この場合は、<code>Field String</code>と<code>Field Bool</code>の場合でそれぞれ定義するしかなさそうです。もしまとめて定義する方法があれば誰か教えてください。</p> <pre><code>data Field typ = (typ ~ String) => Title | (typ ~ Bool) => Done instance Show (Field typ) where show Title = "Title" show Done = "Done" instance ToJSON (Field typ) where toJSON Title = String "title" toJSON Done = String "done" :{ instance FromJSON (Field String) where parseJSON = withText "Field" $ \v -> case v of "title" -> pure Title _ -> empty instance FromJSON (Field Bool) where parseJSON = withText "Field" $ \v -> case v of "done" -> pure Done _ -> empty :} encode Title -- --> "\"title\"" encode Done -- --> "\"done\"" decode "\"title\"" :: Maybe (Field String) -- --> Just Title decode "\"done\"" :: Maybe (Field Bool) -- --> Just Done </code></pre> <p>で、この<code>Field</code>を使って、以下のようなレコードを定義します。</p> <pre><code>:{ data Filter = forall typ. Show typ => Filter { field :: Field typ , value :: typ } :} </code></pre> <p>なぜこんなデータ型を考えているかというと、実は<a target="_blank" rel="nofollow noopener" href="http://hackage.haskell.org/package/persistent">persistent</a>のクラスに、<a target="_blank" rel="nofollow noopener" href="https://github.com/yesodweb/persistent/blob/master/persistent/Database/Persist/Class/PersistEntity.hs#L135">Filter</a>っていうのがあって、これを<code>FromJSON</code>のインスタンスにしたかったのです。このデータをもう少し簡易にしたものが、上で定義した<code>Filter</code>です。ここでの肝は、型引数の<code>typ</code>が型としては明示的に現れていない点です。つまり<code>Filter Title "some title"</code>も、<code>Filter Done True</code>も型としては単に<code>Filter</code>型ですが、前者の<code>typ</code>は<code>String</code>で後者は<code>Bool</code>です。</p> <pre><code>-- どちらも単にFilter型 :t Filter Title "some title" -- --> Filter Title "some title" :: Filter :t Filter Done True -- --> Filter Done True :: Filter </code></pre> <p>このようなデータ型の場合、先ほど<code>Field</code>の<code>FromJSON</code>を<code>Field String</code>と<code>Field Bool</code>でそれぞれ定義した時のようなことができません。<code>field</code>の値が<code>Title</code>なら<code>typ</code>は<code>String</code>、<code>Done</code>なら<code>Bool</code>というような場合分けをする必要があります。色々試行錯誤してようやくできた定義が以下です。<code>mayTitle</code>と<code>mayDone</code>の場合分けのところは、この2つデータの型が違うので、それぞれ別の変数にせざるを得ませんでした。そのため<code>mayField</code>を必ず2回評価することになり、無駄の多い実装になってしまいました。</p> <pre><code>instance FromJSON Filter where parseJSON (Object o) = do let mayField = HMS.lookup "field" o let mayValue = HMS.lookup "value" o let mayTitle = case mayField of Just (String "title") -> Just Title _ -> Nothing let mayDone = case mayField of Just (String "done") -> Just Done _ -> Nothing case mayValue of Just value -> do case mayTitle of Just title -> Filter title <$> (parseJSON value :: Parser String) Nothing -> case mayDone of Just done -> Filter done <$> (parseJSON value :: Parser Bool) Nothing -> empty Nothing -> empty -- Filter Title "some title" case decode "{\"field\":\"title\", \"value\":\"some title\"}" :: Maybe Filter of Just (Filter field value) -> print value Nothing -> print Nothing -- Filter Done True case decode "{\"field\":\"done\", \"value\":true}" :: Maybe Filter of Just (Filter field value) -> print value Nothing -> print Nothing </code></pre> reouno tag:crieit.net,2005:PublicArticle/15415 2019-09-23T09:59:26+09:00 2019-09-26T13:00:18+09:00 https://crieit.net/posts/Haskell Haskellで複雑度測定 <p>※ この記事は<a target="_blank" rel="nofollow noopener" href="https://www.leo-leo.uno/2019/09/23/1050/">Haskellで複雑度測定</a>からの転載です。</p> <p>自分で書いているブログのPVが増えなくて悲しいので、こういうところにも載せて見たら多少増えるんじゃないかと思って試しに載せて見ます。</p> <hr /> <p>Haskellでサイクロマティック複雑度(循環的複雑度)を測定する場合、2つツールがあるようです。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/mgajda/homplexity">homplexity</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/rubik/argon">argon</a></li> </ul> <p>githubのスター数はargonの方が多いのですが、コミット履歴を見るとhomplexityの方が今もメンテナンスされているようなのでhomplexityがオススメです。機能的な違いは特に調べていません。</p> <h3 id="homplexityの機能"><a href="#homplexity%E3%81%AE%E6%A9%9F%E8%83%BD">homplexityの機能</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://www.migamake.com/projects/homplexity.html">公式サイト</a>によれば、以下の統計値を出してくれるようです。</p> <ul> <li>Cyclomatic complexity</li> <li>Code metric</li> <li>Lines of code</li> <li>Branching depth</li> <li>Type metric</li> <li>Comment metric</li> <li>Code to comments ratio</li> <li>Type tree nodes</li> <li>Number of function arguments</li> </ul> <p>本題から外れますがBranching depthってなんでしょうか。説明には</p> <pre><code>Branching is used with conditionals and has been used as a criterion for both software complexity and logic. </code></pre> <p>と書いてあります。分岐の数のことなんでしょうか。ちょっと試して見たところ、if分岐がある場合でも0でしたが、ifの中にifをネストさせると1になり、ifの中にifの中にifとネストさせると2になりました。だから分岐の深さってことか。なんかサイクロマティック複雑度と似ていますね。</p> <h3 id="homplexityのインストール"><a href="#homplexity%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">homplexityのインストール</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://docs.haskellstack.org/en/stable/README/">stack</a>が入っていれば簡単です。クローンしてstack installするだけです。</p> <pre><code class="bash">git clone https://github.com/mgajda/homplexity.git cd homplexity stack install </code></pre> <p>で、<code>~/.local/bin</code>に<code>homplexity-cli</code>ができるはずです。パスを通すなら、<code>~/.bashrc</code>や<code>~/.bash_profile</code>などに</p> <pre><code class="bash">PATH=$PATH:~/.local/bin </code></pre> <p>を追記すれば良いです。</p> <p>これで簡単にインストールできるのは良いのですが、このリポジトリで指定しているGHCバージョンが入っていない場合、そのインストールと依存パッケージのインストールから始めるので<strong>結構時間がかかる</strong>かもしれません。これがstackのデメリットですよね(メリットなのか?cabal hellという言葉を思い出した、そして<a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/50925938/what-is-cabal-hell">What is Cabal Hell?</a>というStackoverflowを見つけたw)。</p> <h3 id="使い方"><a href="#%E4%BD%BF%E3%81%84%E6%96%B9">使い方</a></h3> <p>githubリポにも書いてありますが、以下のようにメインモジュールファイルと依存モジュールのルートディレクトリを指定します。</p> <pre><code class="bash"># プロジェクトディレクトリ構成がこのようになっている場合 root --- app --- Main.hs | |- src --- Lib.hs |- ... homplexity-cli app/Main.hs src/ </code></pre> <p>これで、メインモジュールと依存モジュールファイル群を見つけて各メソッドの複雑度を測定してくれます。出力は、</p> <pre><code class="bash">Warning:src/InterfaceAdapter/Presenter/StockAPIHandler.hs:SrcLoc "src/InterfaceAdapter/Presenter/StockAPIHandler.hs" 34 1:function stockServer has 48 lines of code should be kept below 20 lines of code. Correctly parsed 16 out of 16 input files. </code></pre> <p>こんなのが出てきます。このファイルのこのメソッドが48行もあるから20行未満に抑えた方が良いよ、と言っています。これは複雑度ではありませんが。</p> <p>もっと詳細な情報を出して欲しい場合は<code>--severity</code>というオプションを使います。ログレベルの設定のような感じです。<code>homplexity -h</code>を見てもらえばわかりますが、</p> <pre><code># ヘルプの説明 --severity={Debug|Info|Warning|Critical} level of output verbosity (Debug Info Warning Critical) (default: Warning, from module: Main) </code></pre> <p>とのことなのでデフォルトはWarningですがInfoにすればもっと色々出てきます。以下はInfoで解析した時の出力の一部です。</p> <pre><code>homplexity-cli --severity=Info app/Main.hs src/ Info:app/Main.hs:SrcLoc "app/Main.hs" 1 1:module Main has 14 lines of code Info:app/Main.hs:SrcLoc "app/Main.hs" 8 1:type signature for main has type constructor nesting of 1 Info:app/Main.hs:SrcLoc "app/Main.hs" 8 1:type signature for main has 1 arguments Info:app/Main.hs:SrcLoc "app/Main.hs" 9 1:function main has 8 lines of code Info:app/Main.hs:SrcLoc "app/Main.hs" 9 1:function main has cyclomatic complexity of 1 Info:app/Main.hs:SrcLoc "app/Main.hs" 9 1:function main has branching depth of 0 </code></pre> <ul> <li>メソッドの行数</li> <li>コンストラクタのネスト数</li> <li>引数の数(+1された数字が出ている?Haskellの関数には暗黙的な引数が一つあるのかな?それか単に型一つにつき1とカウントしているのかな?)</li> <li>サイクロマティック複雑度</li> <li>Branching depth<br /> が出てきました。</li> </ul> <p>これは、Makefileなどに書いておいて、毎回ビルドの時に一緒に測定してもらうなどが良さそうですね。それかIDEでファイル保存のトリガーで実行してくれる方が良いのかな。そこで警告などが出てくれればソースコードを見直そうという気になるかもしれません。</p> reouno