PureScriptメモ - Generics

purescript-generics-repパッケージを使ってGenericなSerializer型クラスを作った。以下はそのメモ。 準備 プロジェクトを作成。 $ spago init Arrayを使うので、パッケージをインストールしてsrc/Main.pursにimport文を書き込んでいく。 本記事の本命であるgenerics-rep入れる。 $ spago install arrays $ spago install generics-rep 1 import Data.Array ((:)) REPLで色々実験するので、あらかじめ起動しておく。 $ spago repl > import Main 以降はsrc/Main.pursに色々書き足していく。REPLで:r(もしくは:reload)とコマンドを打てばモジュールが再読み込みされるので、src/Main.pursを書き換える度にこのコマンドを打つと良い。 Serializer そもそもSerializerとは何か。ここでは単に「データをビット列に変換するもの」程度の意味で捉えれば良い。 厳密にはJSONなどの階層を持つデータを,文字列などの平坦なデータに変換するという意味合いとしてシリアライズ(直列化)という言葉を使う。実際、本記事では最終的に木構造をシリアライズする。 まずビットは次のように定義する。 1 2 3 4 5 data Bit = O | I instance showBit :: Show Bit where show O = "O" show I = "I" Serializer型クラスを以下のように定義する。 1 2 class Serializer a where serialize :: a -> Array Bit 試しに適当な型をつくり、それをSerializer型クラスのインスタンスにしてみる。...

2020-11-03 · (updated 2020-11-06) · 6 min · 1114 words

PureScriptでじゃんけんゲーム(CUI)を作る

プログラミングの初歩で作りそうなじゃんけんゲームを作る。ただし、PureScriptで作る。 方針 Jankenというモジュールを作る グー・チョキ・パーをHandとして定義する じゃんけんの勝負の結果をJudgementとして定義する コンピュータが出す手はランダムに出したいので、ランダムな手を出す関数randomを作っておく 入力は文字列にしたいので、文字列から手に変換する関数fromStringを作っておく 入出力はMainに書く。Node.ReadLineモジュールの力で入力を受け付ける。 準備 適当なプロジェクトディレクトリを作っておいて、 $ spago init /src/Main.pursと/src/Janken.pursを作っておく。 /src/Main.pursはとりあえず以下のようにしておく。 1 2 3 4 5 6 7 8 9 10 module Main where import Prelude import Effect (Effect) import Effect.Console (log) main :: Effect Unit main = do log "Hello" 次のコマンドでHelloが出力されることを確認する。 $ spago run Jankenモジュールの定義 この節では/src/Janken.pursを編集していく。 1 2 3 module Janken where import Prelude Handの定義 じゃんけんの手を表す型Handを定義する。 1 data Hand = Rock | Scissors | Paper 余談。これは公式ではタグ付き共用体と呼ばれているもの。Haskellでは代数的データ型と呼ばれているが、正直名前はどうでもいい。データをこのように表現すれば、「データはこの値しかとりえない」という制限が得られる。制限があれば、プログラムのバグも減らせる。たとえば、「グーを0、チョキを1、パーを2」として表現すると、万が一それ以外の値が来た場合に困る。上のようなHandの定義では、「それ以外の値」が入る余地すら与えない。…この話は、Elm Guideの受け売り。...

2020-06-25 · (updated 2020-06-25) · 3 min · 591 words

VimでLaTeXを使うための環境構築(Mac)

備忘録。基本的にはMacのTerminalでやることを想定。Macをインストールしたての状態を仮定する。 homebrewを使って、TeXLiveとSkimをインストールする。latexmkの設定をした後、vimにdein.vimを入れて、それを用いてvimtexを入れるところまでやる。おまけでvimrcの他の設定や、colorschemeの設定もやる。 注意 なるべくコマンドを載せるようにするが、それを実行しても上手くいかない場合は、公式サイトなどを参照すること。この記事が古くなっていて、打つべきコマンドが変わっている可能性がある。 homebrewのインストール homebrewをインストールしておくと、いろいろなソフトがbrew (cack) install ...だけでインストールできる。便利なので入れる。 homebrewの公式サイトのインストールを参照。 念のため、Terminalを再起動しておく。 TeXLive(MacTeX)のインストール TeXLiveの説明についてはWikiを参照。TeX関連のあらゆるパッケージやソフトの詰め合わせ。そのMac版がMacTeX。 MacTeXやそのインストール方法については、Wikiを参照。homebrewをインストールしたので、次のコマンドでインストールできる。以下はmactex-no-guiとしているが、もしguiアプリも入れたい場合はmactexとする。どんなguiアプリが入るのかについてはWikiを参照。 かなり巨大なファイル群のため、インストールにかなり時間がかかった気がする。 $ brew cask install mactex-no-gui $ sudo tlmgr update --self --all $ sudo tlmgr paper a4 念のため、Terminalを再起動しておく。 Skimのインストール SkimとはPDFビュワーの一種で、PDFの自動リロードを行ってくれる。こちらもhomebrewでインストールできる。 $ brew cask install Skim 起動して、環境設定を開く。「同期」タブに移動して、「ファイルの変更をチェック」と「自動的にリロードする」にチェックを入れておく。 latexmkの設定 後でインストールするVimのプラグイン(vimtex)がlatexmkを利用するので、設定しておく。 こちらのページは、latexmkについて分かりやすく説明してくれているので見ておくと良い。 ~/.latexmkrcを作成し、内容を以下のようにする。これは上の参考サイトの引用。 1 2 3 4 5 6 7 8 9 10 11 #!/usr/bin/env perl $latex = 'platex -synctex=1 -halt-on-error'; $latex_silent = 'platex -synctex=1 -halt-on-error -interaction=batchmode'; $bibtex = 'pbibtex'; $biber = 'biber --bblencoding=utf8 -u -U --output_safechars'; $dvipdf = 'dvipdfmx %O -o %D %S'; $makeindex = 'mendex %O -o %D %S'; $max_repeat = 5; $pdf_mode = 3; $pvc_view_file_via_temporary = 0; $pdf_previewer = "open -ga /Applications/Skim....

2020-05-31 · (updated 2020-05-31) · 3 min · 479 words

Eular法とRunge-Kutta法をPythonで実装する

備忘のために。数値解析関連の話はほとんど学んだことがないため、何か間違いがあるかも。 Eular法 以下、例に出そうとしている微分方程式が運動方程式なので、文字の使い方を力学っぽくしている(位置、速度、時間を $x, v, t$ みたいな気持ちで書いている)。 導出(1階) まず次の常微分方程式がある。 \[ \frac{dx}{dt} = f(t, x) \] 上の式を以下のように近似する。$h$を十分小さくすれば、微分の定義より上の式に近づく。 \[ \begin{aligned} \frac{x(t + h) - x(t)}{h} \simeq f(t, x) \\ \Rightarrow x(t + h) \simeq x(t) + f(t, x)h \end{aligned} \] これが、$x(t)$の更新式となっている。つまり、ある時刻$t_0$における値$x_0 = x(t_0)$を決めておけば、 \[ \begin{aligned} & t_k := t_{k-1} + h\\ \end{aligned} \] とおいて、 \[ \begin{aligned} & x(t_1) := x(t_0) + f(t_0, x_0)h \\ & x(t_2) := x(t_1) + f(t_1, x_1)h \\ & x(t_3) := x(t_2) + f(t_2, x_2)h \\ & … \end{aligned} \]...

2020-05-28 · (updated 2021-03-31) · 8 min · 1520 words

HaskellでStateモナドを自作する

Stateモナドがわからない状態から、ギリギリ分かる状態になった。 Stateモナドを学習した流れ 結局、具体例を通して学習した。個人的には、いきなりモナドの定義から学習するよりも、たくさんの例を見たり、実際に例を作ってみたりした方が覚えられた。抽象的な概念を理解するためには具体的な概念に触れるべきだ、ということを改めて認識した。 以下は、自分が行った学習の流れ。Haskell IOモナド 超入門は学習のうえで参考になった。とくに、>>=を漏斗の形に見立てる比喩のおかげで、モナドと関数の組み合わせのイメージがクリアになった。 Maybeモナド、Listモナドの使い方を理解する。 IOモナドの使い方を理解する。 いくつかのモナドについて、do構文を>>=に書き換えてみる。 Stateモナドの使い方を理解する。 Stateモナドを自作する。 この記事ではStateモナドを自作することをテーマとしているため、ある程度Stateモナドに慣れた人でないとわかりづらいかもしれない。 Stateの定義 まずはStateを自作する。Stateは、状態 -> (計算結果,次の状態)という関数を内部に持っている。この関数のことを、この記事では「内部関数」「状態付き計算」などと表現する。 1 newtype State s a = State (s -> (a, s)) これは本来のStateの定義とは異なることに注意。本来は、StateはStateTを使って実装されている。上のように定義してしまうと、モナド変換子としての機能が利用できない。ただ、そこまで考えると面倒なので、今回はStateを単なる関数のラッパーとして定義した。 型引数の順番と内部関数が返すタプルの順番が逆なのが微妙に気持ち悪い。これはあくまで推測でしかないが、 あくまで状態付きの計算なので、重要なのは計算の結果。なので返り値は(a, s)と計算結果を先に書いている。 型引数の順番がs aなのは、Monadにするときに不都合を生じないため。 なのだと思う。 余談 Stateモナドがよくわかっていない時は、Stateのことを「状態を持つ型」と勘違いしていた。正しくは、「状態付き計算を持つ型」。Stateは状態を持っているわけでなく、あくまで、「状態を引数にとり、計算結果と次の状態を返す関数」を持っている。なので、初期状態は内部関数の引数として、自分で投入する。 runStateの定義 レコード構文を使って、runStateを定義する。runStateは、Stateから中身の関数を取り出す関数。 1 newtype State s a = State { runState :: s -> (a, s) } 試す 上の定義を踏まえて、次のようにプログラムを書いてみる。以下は、状態を[Int]とする状態付き計算。 addX doubleAll sumUpはそれぞれ、単純な内部関数を持つStateである。一方で、calc0はこれらの関数を組み合わせた、新たなStateであることに注目。一連の状態付き計算を一つにまとめて、新たな状態付き計算を作っている。 calc0において、初期状態をs、次の状態をs0、その次の状態をs1、…と置いている。計算結果を返すのはsumUpだけで、他の関数は単に状態を変更するだけ。なので計算結果は()となっている。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 addX :: Int -> State [Int] () addX x = State $ \s -> ((), x:s) doubleAll :: State [Int] () doubleAll = State $ \s -> ((), map (* 2) s) sumUp :: State [Int] Int sumUp = State $ \s -> (sum s, s) calc0 :: State [Int] Int calc0 = State $ \s -> let (_, s0) = runState (addX 1) s (_, s1) = runState (addX 2) s0 (a2, s2) = runState sumUp s1 (_, s3) = runState (addX a2) s2 (_, s4) = runState doubleAll s3 in runState sumUp s4 main = do print $ runState calc0 [] 実行結果は以下のようになる。...

2020-03-28 · (updated 2020-03-29) · 8 min · 1531 words

webpackに入門する - p5.jsの開発環境作り

webpackを利用してp5.jsの開発環境を作り、ボールが弾むプログラムを作成する。 使用するパッケージのバージョン 1 2 3 4 webpack@5.15.0 webpack-cli@4.3.1 webpack-dev-server@3.11.2 p5@1.2.0 動機 ふとしたきっかけで久々にp5.jsを触りたくなった。 昔使っていたときは、p5.jsのファイルをダウンロードしてscriptタグに直接指定することで書いていた。しかし最近、Vue.jsのガイドを読んでいてwebpackの存在を知った。名前は知っていたのだが、具体的に何をするためのものなのかはよく分かっていなかったので調べた。 webpackとは 以下、個人的に調べた限りの理解を書く。 Conceptによれば、webpackとは"module bundler"の一種。bundleという意味から、「複数のモジュールを一つに束ねるツール」だと予想できる。JSのプログラムを、モジュールとして複数の単位に分割して開発する。それを一つのファイルにまとめ上げてくれるのがwebpack。 例えばp5.jsで、ボールが弾むだけのプログラムを書こう、と思った場合、 ボールを管理するモジュールをBall.jsに書く スケッチを管理するモジュールをsketch.jsに書く メインの処理をindex.jsに書く みたいにモジュールを分けられる。 ただし、モジュールを扱うための機能であるimport/export文はES2015の仕様で標準採用され、多くのブラウザで実装されている。じゃあwebpackの他の強みは何かというと、おそらく「JS以外のファイルもまとめてくれる点」だと思う。例えばcssやsassのファイルもJSに埋め込むことができる。TypeScriptやJSXのファイルもwebpackでまとめられる。ただしwebpackの核の機能はあくまでJSのモジュールをまとめることなので、JS以外のファイルはloaderと呼ばれる変換器を通しておく必要がある。とはいえ、「このファイルはこのloaderに通してね」というのをあらかじめ設定ファイルに書いておけば、少ないコマンドで変換からbundleまでやってくれるので、便利である。 今回はp5.jsの開発環境づくりのためにwebpackを用意するのだが、JSのモジュールしか扱うつもりはない。なのでwebpackの恩恵は少ないかもしれない。しかし練習として使ってみる。 webpackの導入と動作確認 まず適当にプロジェクト用のディレクトリを作る。npmでプロジェクトを初期化する。 $ mkdir p5-sandbox $ cd p5-sandbox $ npm init -y 以下、このプロジェクトのルートディレクトリを/で表す。 webpack本体を入れる。webpackをコマンドラインから実行するためにはwebpack-cliが必要なので、それも入れる。個人で使う分にはどうでもよいと思うが、これらは開発のみに利用されるパッケージなので、--save-devをつけておく。 $ npm install webpack webpack-cli --save-dev ディレクトリの作成 今回は次のようにする。 ソースコードは/src/index.jsに書く。 bundle後のファイルは/public/js/bundle.jsとして出力されるようにする。 あらかじめディレクトリを作成しておく。 $ mkdir src $ mkdir -p public/js index.jsの作成 /src/index.jsを作成。動作確認のため適当に書く。 1 console.log("Hello, World"); webpackの設定 /webpack.config.jsを作成する。 1 2 3 4 5 6 7 8 9 10 const path = require('path'); module....

2020-03-19 · (updated 2021-01-17) · 3 min · 629 words

zipファイルの構造を少しだけ理解する

Unix系のコマンド(od、grep)だけを使って、zipファイルの中身をのぞく。 zip形式の参考サイト zipの仕様書はZIP File Format Specificationで確認できる。ページ内検索をかけながら必要なところをつまんでいく、という読み方が良さそう。 日本語ならWikipediaがある。こちらは図が書かれているし日本語なので分かりやすい。 zipファイルの用意 まずはzipファイルを用意する。 foo.txtとbar.txtを用意する。 $ echo "Hello, World." > foo.txt $ echo "Good Bye." > bar.txt これらをzipコマンドでまとめる。 $ zip tmp.zip foo.txt bar.txt バイナリ形式で出力 zipファイルはテキストとして表示できるものではなく、バイナリとして表示しないとあまり意味を掴めない。バイナリ表示ができるテキストエディタを使ってもよいが、ここではodコマンドを用いる。 $ od -Ax -tx1z tmp.zip 引数の意味は以下の通り。man odでも確認できる。 -A: アドレスの基数(Address-radix)。出力時、最も左の値がファイル先頭から何バイト目なのかを表示する。続けてxと書くと、16進数(hex)で出力する。 -t: データの出力形式(おそらくtypeの略)。 続けてx1と書くと、1バイト区切りの16進数で出力する。 続けてzと書くと、右側にテキストでの表示を添える。ただし表示されるのはASCIIコードで認識される文字のみ。 結果は以下のようになる。 000000 50 4b 03 04 0a 00 00 00 00 00 28 70 64 50 4b 82 >PK........(pdPK.< 000010 70 33 0e 00 00 00 0e 00 00 00 07 00 1c 00 66 6f >p3....

2020-03-04 · (updated 2020-03-06) · 14 min · 2935 words

Elmメモ ドラッグ移動の実現(2) - elm-draggableの利用

前回はBrowsertやSvgなどの標準的なパッケージを利用してドラッグ機能を実現した。今回はelm-draggableというパッケージを使ってドラッグ機能を実現してみる。 準備 Elmのプロジェクトを作成して、src/Main.elmとsrc/Circle.elmを作成。 Circle.elm 前回と同じなのでコードだけ載せる。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 module Circle exposing (....

2020-02-27 · (updated 2020-02-27) · 6 min · 1148 words

Elmメモ ドラッグ移動の実現(1)

ElmでSVGの要素をドラッグ移動したいと思った。ドラッグ操作を実現するパッケージにelm-draggableがある。今回は勉強として、それに頼らず実装することを試みる。elm-draggableを用いた方法については次回やる。 初期状態 詳細は省略するが、Elmプロジェクトを作成してelm/svgとelm/jsonをインストールしておく。 src/Main.elmは以下のようにしておく。elm reactorで動くことを確認する。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 module Main exposing (..) import Browser import Browser.Events as BE import Html exposing (..) import Html.Attributes exposing (..) import Json....

2020-02-25 · (updated 2020-03-04) · 8 min · 1588 words

Vue.js勉強メモ(1) - 簡易Todoリストの作成

公式ガイドの、コンポーネントの詳細の手前まで読み終えたので、この時点でTodoリストっぽいものを作ってみる。データベースを用意しないため、厳密にはTodoリストではない。 コンポーネントについてはまだ学んでいないため、これから書くコードにはまだ改善の余地があるだろう。 準備 index.htmlを用意する。 1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html> <html lang="ja"> <head> <meta charet="utf-8"> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <h1>Todo List</h1> <script src="script.js"></script> </body> </html> 以下の部分でVue.jsを読み込んでいる。 1 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> script.jsを作成しておく。中身はまだ空。 実装する機能 初めにも述べたが、データベースは用意しない。以下の簡単な機能だけ実装する。 入力エリア Todoリスト表示エリア 各要素に削除ボタンをつける。 勉強を兼ねて、いくらか遠回りしながら作っていく。 配列の要素をli要素として表示 index.htmlに追記する。 1 2 3 4 5 <div id="app"> <ul> <li v-for="todo in todos">{{ todo }}</li> </ul> </div> Vue.jsが用意したテンプレート構文をHTMLに埋め込むことによって、データとDOMを結びつけることができる。v-という接頭辞がついた属性はディレクティブと呼ばれる。今回のv-forディレクティブは、その名の通りfor文を実現する。構文から分かると思うが、JSとかPythonで使われているfor-in文と同じ文法。 式の埋め込みは{{ 式 }}で行う。ガイドではMustache(口髭)構文と呼んでいる。良いネーミングだなと思ったけど、{{ }}の書式をそう呼ぶのはわりと一般的みたい? さて、そうするとtodosというデータを用意する必要がありそうだが、これはscript.jsで行う。 1 2 3 4 5 6 const app = new Vue({ el: '#app', data: { todos: ['todo1', 'todo2', 'todo3', 'todo4', 'todo5'] } }) elプロパティに、データと結びつく要素を指定する。これはセレクタの書式。elとは恐らくelementの略。dataプロパティに、結びつけるデータを指定する。v-forで利用するために、todosプロパティは配列にする。...

2020-02-16 · (updated 2020-02-16) · 2 min · 306 words