Haskellでわかる群論の代数的構造をやってみました。

私は数学の教科書で問題を解こうとすると眠くなります。けれど、プログラミングになると眠くなりません。なので、代数の基本をプログラミングで試せるaiya000さんのgitbook「Haskellでわかる群論の代数的構造」をやってみました。

gitbookは群、グループまで書かれていますが、ソースコードのほうは環、リングまで書かれていました。

stackの場合、.cabalファイルにhspecとQuickCheckと書くと、すぐに使えて、stack build –testで、ビルドとテストを実行できます。

hw.cabalについて

.cabalファイルには、src/Group.hs、src/Semigroup.hsのようにモジュールを追加したら(ここでいうモジュールとは、ファイル一行目のmodule Group whereの事)、そのたびにexposed-modulesに追加していきます。

あとは、test-suite hw-test:のところには、build-dependsにhspecとQuickCheckを追加しました。

 

src/Group.hs

test/GroupSpec.hs

Spec.hs

 

まとめ

プログラミングの場合は、言葉の定義を何回も見返したりして、それをコメントに書いて、さらに実装しテストをするので、思っていた以上に数学に対して、抵抗なく学んでいけています。

今回は、Haskell,Stackという構成なので、近いうちにgithubにアップロードしたいと思います。

Windows10+Stack+ATOMでのトラブル対応

ghc-modをインストール時などで、old-timeのビルドエラーが発生する場合

私の場合は、Windows10にHaskell Platform 8.0.1 を再インストールしたり、stack install ghc-modコマンドを実行したときに発生しました。

https://github.com/haskell/old-time/issues/3

Haskell Platformは、インストール後、システム環境変数PATHに以下を追加します。Haskell PlatformはmingwとmsysというLinuxのツール群も一緒にインストールされます。しかしmsys\usr\binはなぜかPATHに設定されません。old-timeはこれがあればビルドができます。

システム環境変数PATH

  • C:\Program Files\Haskell\bin
  • C:\Program Files\Haskell Platform\8.0.1\lib\extralibs\bin
  • C:\Program Files\Haskell Platform\8.0.1\bin
  • C:\Program Files\Haskell Platform\8.0.1\mingw\bin

また、Stackのインストールで、ユーザー環境変数PATHにも以下が設定されます。

  • C:\Users\xxxxxxx\AppData\Roaming\local\bin

システム環境変数PATHに以下を追加しましょう。

C:\Program Files\Haskell Platform\8.0.1\msys\usr\bin

ATOMのghc-modでエラーが出るときの対応方法

ATOMエディターのhaskell-ghc-modパッケージは、エラーのスタック情報を表示するだけなので凄くわかりづらいです。それで、このエラーはhaskell-ghc-modの不具合ではなく、ghc-modがエラーを出している場合があります。つまりATOM側の問題ではないです。

そのため、非常に面倒ですが、PowerShellでghc-modコマンドを実行すると解決できる場合があります。

ghc-modで、hGetContents: invalid argument (invalid byte sequence)が発生する

これは何も設定せずにstackを使った場合、.hsファイルのコメントに日本語があった場合でも発生します。

ghc-mod: C:\Users\xxxxx\workspace_haskell\hw\src\Semigroup.hs: hGetContents: invalid argument (invalid byte sequence)

まさかデフォルトでUTF-8のhsファイルに日本語のコメントを書けないとは思わなかったので、最初はATOMエディターのhaskell-ghc-modのバグと思ってました。

HSpecテストを試してみたら、ghc-modでエラーが発生した。

StackでHSpecを使う入門サイトなどを調べていると、Spec.hsに以下を記述すれば自動でSpecファイルを検知してくれると書かれています。

これだけだと、ATOMエディターで上記画像のような赤いエラーメッセージが表示されました。対応としては、hspec-discoverをstack経由でインストールします。

 

StackでHSpecでstack testを実行するとHUnit、QuickCheckも用意される?

Stack を使って Haskell したい!! を参考にHSpecを書いてみました。.cabalファイルのbuild-dependsにhspecを追加して、コンソールから、stack testを実行したら、依存関係で、HUnit、QuickCheckもダウンロードしてビルドされているようです。

プロジェクトの.cabalにhspec追加

 

Lib.hs

LibSpec.hs

Spec.hs

 

cabalをちょっと使ってみた感想

昨日まで、Windows10でHaskell+ATOMエディター+プロジェクト管理ツールStackを使ってみて、ATOMでghc-modがうまく動かず、一度すべてアンインストールして、Windows10+Haskell+Cabal+ATOMエディターという環境を構築してみました。

使ってみて良かったところ

  • 速い
  • ATOMで問題なくghc-mod使える
  • .cabalファイルが何か分かった。

cabalとstackの関係

Haskellでは2015年ごろにstackというツールができて、最近はこれが推奨されているようです。stackコマンドでプロジェクトを作成して、ビルド、テスト、ライブラリ依存管理などができます。

それ以前まではcabalが使われていました。現在のcabalはsandboxという機能でプロジェクト単位にライブラリーのバージョン管理ができますが、初期のcabalはOSのアカウントでライブラリー管理をするため、異なるプロジェクトや、githubからとってきたプロジェクトで、ライブラリーのバージョンを調整する必要があり大変だったそうです。

https://sites.google.com/site/toriaezuzakki/haskell/environment#TOC-sandbox-

cabalのしんどいところ

stackではプロジェクトを新規に作成したらテスト用のフォルダーも作成してくれてすぐテストができますが、cabalは設定ファイルを書いて用意する必要があるため面倒です。

公式のユーザーガイドも出来があまりよくなく、依存関係をどう書いていけばいいかわかりません。

https://www.haskell.org/cabal/users-guide/developing-packages.html#test-suites

いろいろ調べていて以下を見つけました。

http://taylor.fausak.me/2014/03/04/haskeleton-a-haskell-project-skeleton/

これを参考にしようと思ったのですが、これを今から試すならstackやったほうがよさそうです。

Windows10にATOM+Haskell+Cabel環境を構築する

Windows10でStackの環境を構築しましたがghc-modがATOMでうまく動かず、Stackも重すぎたので断念しました。

Haskellのインストール

Haskell+Cabalの場合は、おそらくWindowsでも問題ないはずなので、こちらを構築してみます。まずは、HaskellのMinimal installersでHaskellをインストールします。インストール時にいろいろ選択肢がありますが、Stackは使わないのでインストールしませんでした。

ghc-modのインストール

上記をインストールすると環境変数の設定もしてくれるので、ghcコマンド、cabalコマンドが使えるようになっています。そのためこの時点でHaskellの開発は問題なくできます。

cabalはパッケージ管理で、ghc-modとエディターを組み合わせると開発効率が良くなるので、cabalからghc-modをインストールします。

上記のように、old-time-1.1.0.3の依存関係のインストールに失敗してghc-modがインストールできません。

cabal/configの修正

Haskell Platformをインストールすると内部では、MSYS+Cygwinのコマンドやライブラリーなどが同時にインストールされますが、それらはパスが通ってません。そのため以下のように、パスを設定します。

configファイルは、C:\Users\*******\AppData\Roaming\cabal\configにあります。configファイルは、–がコメントです。

50行目付近

これでひとまず、ghc-modがインストールできるようになりました。cabalの使い方を調べてみます。

インストール先

C:\Users\*******\AppData\Roaming\cabal\bin

Haskell Platformをインストールしたときにこの環境変数にパスが通っているため、cabalコマンドでインストールしたものがすぐにコマンドプロンプトやPowerShellで使えます。

hlintとstylish-haskellをインストール

以下などを参考にインストールします。

http://qiita.com/manji-0/items/463ea051f624a9a4a83a

cabalの簡単な使い方

ビルド

実行

テスト

テストは、テスト用のライブラリーを追加したりする必要がありますが、cabal install でライブラリーをインストールした後は上記コマンドとエディターが開発していけます。

実際には、cabal runで、ビルドされていない場合は、cabal buildが実行されるので、修正してcabal runでよさそうです。

ATOM+Haskell+Cabal環境をWindows10で構築して

Stackがとても重く、ATOMでghc-modが動かなかったのが嘘のように快適です。cabal runを実行してコンパイルが実行されても許容範囲でコンパイルが終わる(当たり前ですが…)のでストレスがありません。「すごいHaskellたのしく学ぼう!」ぐらいのレベルの人は、まだStackはインストールしないほうが良いです。

Windows10のStack+ATOMのHaskell環境を断念

Windows10にStack+ATOMのHaskellの環境構築」でHaskellがプログラミングできる環境を用意しましたが、ATOMでghc-modがうまく動かず、Stackが重すぎるのでこの構成で使うのはひとまずやめることにしました。

ATOMでghc-modがうまく動かない

初心者レベルで文法を学んだ時の感想ですが、ATOMが非常にもっさりしています。私のPCは最近の3Dゲームがある程度動くような環境で、Visual Studio CodeやVisual Studioなどは問題なく動作するので、ATOM側にいろいろ問題がありそうです。(https://github.com/atom-haskell/haskell-ghc-mod/wiki/Using-with-stack)

Windows10でHaskellのStackが重すぎる

Stackが重すぎます。ファイルが1つ、2つで関数が数個しかないのに、stack buildコマンドでビルドすると数秒待たされます。stack exec helloworld-exeでも数秒待たされます。Stackはプロジェクト管理ツールとしてテンプレートを用意してくれるため「これだ!」って思ったツールなので使っていきたいのですが、如何せん重すぎて使えません。

仮想環境にUbuntus/emacs/cabelの環境があるので結局それを使いますが、Windows10ですべてアンインストールしてcabal環境も作ってみようと思います。

 

 

FSharpでmatch式をつかった直積の書き方

JavaやC#の場合、二重のfor文を実行すれば、x,yの直積が完成します。F#でもリストの内包表記で、二重のforにより直積が作れます。関係代数について調べていた時に、stackoverflowにmatch式を使った直積の書き方を見つけました。

関係代数やリレーショナルデータベースは、集合と関係してくるので、数学の集合論や関数型プログラミングで写像とかで学んだ知識がそのまま使えるのはうれしいです。

http://www.cs.reitaku-u.ac.jp/infosci/rdb/rdb02.html

関係代数

ラムダ計算、チャーチ数をF#で試したときのURL集

関数型言語fのラムダ計算で引き算ができません の記事を書いたときに多くのラムダ計算の資料にお世話になりました。また試すときに忘れそうなので、URLを残しておきます。

関数型プログラミング言語F#初心者向けURL集

関数型プログラミング言語F#を学んでいくうちにいろんなサイトを見つけたので整理すると同時に公開して情報共有します。

関数型の考え方が分かるサイト

F# for fun and profit は英語のサイトなので大変ですが、Learning  F# で関数型で考える心得や、やっていいこと悪いことなどを説明しています。また、Thinking functionally は他の入門サイトと異なり、集合、写像、関数の簡単な説明から始まります。英語ですが関数型プログラミング言語でこの土台が分かるとHaskellやStandardMLなどの基礎部分は同じものとして理解することができます。英語を読むのは本当に大変ですが、このサイトはお勧めです。

文法を学習するために便利なサイト

普通リファレンスは厳密で難しい場合が多いですが、マイクロソフト公式のF# 言語リファレンス は、説明とともに、すぐ動かせる小さなサンプルが豊富にあります。なので、適当な入門サイトでおおよその文法を学んだあとは、このリファレンスを観るのが効率が良いです。

かずきのBlog@hatena さんのサイトで、以下のURLに、F#の文法の記事が25個ぐらいあります。

 

 

興味深い資料

プログラミングで同値関係が分かる!

数学の「関係と集合」まで進んだら、同値関係(Equivalence relation)の説明で、反射律、対称律、推移律、反対称律が出てきました。教科書の言い回しは難しくて何言っているのか分からなかったのですが、プログラミングで考えれば簡単なことでした。関係演算子の機能チェックをするルールを律と言っているだけでした。

プログラミングで使う演算子のおさらい

私たちは普段何気なく使っていますが、演算子はいくつかグループに分けられます。それでイコール記号や大なり小なりは関係演算子と言います。

算術演算子 + - * / %など

関係演算子 == != < <= > >=

論理演算子 && || !

関数型言語の演算子を見てみる

F#のような関数型プログラミング言語では、算術演算子、関係演算子、論理演算子は、どれも関数として使えます。1 + 1のような加算演算子は、中置記法で使いますが、()を使うと前置記法にできます。この前置記法は、プログラミングで私たちが良く作る関数と同じ順番です。関数名、第一引数、第二引数となっています。

JavaScriptの場合は、add関数を作ってx + yをその中に書けば、算術演算子+を別名のadd関数として作れます。

関数型言語の場合は、先ほどの前置記法があるので、add関数で包むという感じではなく、別名を用意する感じです。以下のようになります。

 

ここでひとつ分かることがあります。私たちはプログラミングで演算子を使っていますが、関数で演算子を包んであげれば、関数として使えて、add(x,y)のように、名前を前に持って来ることができます。

等号の関数を作ってみる

JavaScriptの場合は、==で、値が同じかどうかを比較するので、この演算子をeq関数で包めば等号の関数が作れます。

F#の場合は、=が値が同じかどうかを比較します。かなり省略した表記なので、なれないと見づらいです。

ここまでで、add関数、eq関数を作ってみました。これらは+演算子や=演算子と同じように使えます。

K演算子を作ってみる

謎のK演算子を作ってみます。といっても、以下のようにプログラミング言語に演算子Kを追加することはできません。

ですが、add関数やeq関数と同様に、K関数を作って演算子に見立てることはできます。K演算子の中身はなんでもいいのですが、「3で割ったときのあまりが等しい」という演算子にしてみます。

JavaScriptだと以下のような感じです。

F#だと

K関数(K演算子)を作ってみました。ここで問題ですが、K関数(K演算子)は、どのような機能を持っているのでしょうか、=演算子と同じ機能を持っているのでしょうか、それとも>演算子と同じ機能でしょうか、>=と同じ機能でしょうか。

この性質チェックをするのが、数学でいう、反射律、対称律、推移律、反対称律です。何々律というのは実際にはもっとたくさんありますが、教科書では必要な部分しか説明していません。

それで、反射律、対称律、推移律の3つをパスできれば、同値関係つまり、プログラミングの==記号と同じですという事ができます。もしK関数(K演算子)が、同値関係なら、==演算子としても使えるという事になります。

また順序関係もあり、こちらは、反射律、推移律、反対称律、全順序律を満たす必要があります。もしK関数(K演算子)が、順序関係なら、大小の比較にも使えるという事になります。

書きかけのソースコード

正しくない部分があると思いますが、ひとまず雰囲気だけでも分かると思いますので、書きかけのソースコードも載せておきます。

 

 まとめ

数学の問題を解くのではなく、どうにかしてプログラミングの問題にしてしまえば続けられるのが分かってきました。

参考資料