NatureOfCodeの遺伝的アルゴリズムをすこし関数型プログラミングのように実装

NatureOfCodeのサンプルは、初心者にもわかりやすいif文やfor文が使われている文法ですが、最近のモダンな言語はmap/reduceのように関数型プログラミングの文法やAPIを取り入れているので、JavaScriptでまずはfor文を使わない実装を試してみました。

実装する前は、for文をforEachやmapに置き換えるのは大変と考えていましたが、実際にやってみると特に大きな躓きはありませんでした。関数型プログラミングに対する否定的な先入観が大きかったようで、実践的なプログラミングで試してみてそれが大きな間違いだと気づきました。

また、以下を少し意識するだけで、此処の関数がテストしやすくなり実践的なプログラミングで関数型プログラミングの良さを感じられました。

  • メソッドチェーン
  • 小さな関数に分割していく
  • constキーワードによる変数の定数化

以前F#を勉強したときは、あくまでも関数型プログラミングの勉強で演習問題を解くだけだったのですが、新しいプログラミングを勉強した際には、まとめとして実践的なプログラミングを書くことも大切なのを痛感しました。

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環境も作ってみようと思います。

 

 

FParsecのチュートリアルでJSONParserをVisualStudio2015で実行する方法

Haskellのパーサーライブラリーparsecは、いろんな言語に移植されていてF#でもFParsecがあります。今回はVisual Studio 2015で、FParsec 日本語チュートリアル – a wandering wolf を試してみました。

使ってみた感想

まさか自分でJSONパーサーを作って動かすことができるような日がくるとは思ってもみなかったのでとてもうれしいです。関数型プログラミングを勉強すると再帰をたくさん使うので、以前よりBNFの再帰構造にも抵抗なく取り組めました。まだ使い慣れていないので、難しい問題に取り組むよりかは、iniファイルなどを自分で実装してみたいです。

FParsec,FParsecCSをロードする方法

F#でfsファイルを使うときにF# InteractiveにDLLライブラリーをロードさせる方法 手動で、FParsec,FParsecCSをロードする方法を上記に書いています。

参照設定を手軽にfsxファイルに取り込む方法

ソリューションエクスプローラの[参照設定]を右クリックすると[Generate References for F# Interactive]がコンテキストメニューに表示されるのでそれを右クリックスト、Scriptsフォルダーが作成され、load-project-debug.fsx、load-references-debug.fsxが作成されます。load-project-debug.fsxの中で、load-references-debug.fsxを読んでいます。私たちがfsxで読み込むのは、load-project-debug.fsxになります。

この例のように、CSVParserプロジェクトで、HelloParser.fsxなどを新規作成する場合、fsxファイルに、以下のような#load文を書けばロードできるようになります。注意点としては、Scripts/のようにScriptsフォルダーを指定しないといけない事です。

参照設定は、NuGetでライブラリーを取得したり、既存のライブラリーを参照に追加した場合のみへんこうされます。なので面倒ですがそのたびにこの手順を踏む必要がありそうです。

load-references-debug.fsxの書き換え

[Generate References for F# Interactive]で、load-references-debug.fsxを生成した時は、以下のように、FPharsec.dll、FParsecCS.dllという順番になっています。

FPasrsecのDLLは、FParsecCS.dll、FParsec.dllの順番でF# Interactiveに読み込ませる必要があるので、コピーペーストで、FParsecCS.dllとFParsec.dllの順番を入れ替えます。

これで、Ctrl+Aでファイルを全選択して、Alt+Enterで、F# Interactiveにファイルを流し込めます。

文法の単純な見落としに注意

以下が正しいソースコードですが、

以下のように書いて、コンパイルエラーが取れずに頭を抱えてしまいました。

F#では、リストの区切り文字は、セミコロンで[要素1;要素2;要素3]のように記述します。また、複数行にした場合は、セミコロンを省略できます。よって、以下2つは同じです。

普段、Ctrl+K,Ctrl+Dで整形をしますが、以下のような書き方だと、当たり前ですがフォーマッターは、要素1の引数と判断してしまい、整形することはできません。

jobjectの書き方やFPharsecのライブラリーのロードに問題があると思いずっとそちらを調べていたのですが、実際は単純な文法エラーでした。

 

チュートリアルを試した感想としては、もし問題が発生した場合はソースコードをソースコードの入手方法

FParsec Documentation – 3 Download and installation の3.2の部分に以下の引用がありソースコードがFParsecのzipファイルがありその中のSamples/JSONに今回のサンプルのソースコードがあります。

You can “clone” the source code using Mercurial (HG) or you can download it as a zip‐file.

 

ソースコード

最後の行に、runParserOnFileで、実行する行を追加しています。

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を残しておきます。