Scala exercises for beginners をやってみた。

https://gist.github.com/horiuchi/5106615

scalaで何か書いてみようと、手始めに λ Tony's blog λ - Scala exercises for beginners をやってみました。解答は上記のGistに置きました。
問題としては scalaの構文を覚えることと関数型的な書き方に慣れるためのものです。なので、普通に再帰で書く場合と、foldrを使った畳み込みでやる場合の2通りで書いてみました。

Haskellっぽく、解けたので問題自体は難しくなかったです。
書いていて気になったのは、foldrにlambdaを渡す際に引数の型を明示しないとならないのがちょっと違和感。scalaでは型は基本的に明示するものということなんですかね?型推論はそれほど強くないのかな?
今まで HaskellC# では、特に明示しなくても推論されていたので、違いが気になりました。

続きを読む

Windowsで Haskellの persistent-postgresqlモジュールをインストールする方法

Haskellの Persistentで PostgreSQLを使ってみようと思ったのですが、モジュールをインストールのに色々とハマったので手順をメモしておきます。

インストールする環境は以下の通り。現時点での最新のHaskell Platform を使用しています。

素の状態で、以下のコマンドを実行して「persistent-postgresql」をインストールしようとすると、

$ cabal-dev install persistent-postgresql

こんなエラーメッセージが出てインストールに失敗します。

Configuring postgresql-libpq-0.8.2.1...
setup.exe: The program pgconfig is required but it could not be found.
(中略)
persistent-postgresql-1.0.3 depends on postgresql-libpq-0.8.2.1 which failed to install.

persistent-postgresqlが依存している、postgresql-libpq をインストールする際に、PostgreSQLのファイルが必要になります。
その他いくつか必要なファイルがあるため、それぞれインストールして行きます。

PostgreSQLのインストール

PostgreSQLWindows版のインストーラが用意されているので、それを使ってインストールすればOKです。ただし、Haskell Platformは 32bit版しか用意されていないのでインストールするPostgreSQLも 32bit版にする必要があります。
PostgreSQL Download | EnterpriseDB このページの「Win x86-32」をクリックすればインストーラがDownloadできます。それをインストールしてしまいましょう(デフォルトでは『C:\Program Files (x86)\PostgreSQL\9.2』にインストールされるので、そこにインストールしたことにします)。

インストール後に、モジュールのインストール時に必要になるファイルは、Haskell Platformのbuild時にPATHが通った場所に置く必要があります。そのため、以下のコマンドを実行して必要なファイルをコピーしておきます。

$ cd /c/Program\ Files\ (x86)/PostgreSQL/9.2
$ cp bin/pg_config.exe /c/Program\ Files\ (x86)/Haskell\ Platform/2012.4.0.0/mingw/bin
$ cp lib/libpq.dll /c/Program\ Files\ (x86)/Haskell\ Platform/2012.4.0.0/mingw/bin
$ cp lib/libpq.dll lib/pq.dll

その他必要なファイルの入手

インストール時に、Haskell Platformのmingw環境でbuildが走るため、PostgreSQLの依存DLLを別途入手する必要があります。今回は GNUWin32プロジェクトから必要なDLLをDownloadすることにします*1

libintl.dll

LibIntl for Windows より、Binaries をDownloadします。解凍した binフォルダの中に libintl3.dll があるので、以下のコマンドで Haskell Platformへコピーします。

$ cp bin/libintl3.dll /c/Program\ Files\ (x86)/Haskell\ Platform/2012.4.0.0/mingw/bin
$ cp bin/libintl3.dll /c/Program\ Files\ (x86)/Haskell\ Platform/2012.4.0.0/mingw/bin/libintl.dll
ssleay32.dll

OpenSSL for Windows より、Binaries をDownloadします。解凍した binフォルダの中にあるdllを同様に、以下のコマンドで Haskell Platformへコピーします。

$ cp bin/*.dll /c/Program\ Files\ (x86)/Haskell\ Platform/2012.4.0.0/mingw/bin
$ cp bin/libssl32.dll /c/Program\ Files\ (x86)/Haskell\ Platform/2012.4.0.0/mingw/bin/ssleay32.dll

モジュールのインストール

これで必要なファイルが揃ったはずです。後は以下のコマンドでインストールが完了するはずです。

$ cabal-dev install persistent-postgresql --extra-include-dirs=/c/Program\ Files\ \(x86\)/PostgreSQL/9.2/include --extra-lib-dirs=/c/Program\ Files\ \(x86\)/PostgreSQL/9.2/lib

しかし、これではまだ安心できません。最後にexeをbuildしておきましょう。

$ cabal-dev install

以上で、完了です。お疲れ様でした。

それでもまだエラーが出る場合

実行時に、DLLが足りないというエラーがでる場合があります。その場合には上記の GNUWin32プロジェクトから、指定されたDLLを /c/Program\ Files\ (x86)/Haskell\ Platform/2012.4.0.0/mingw/bin に入れてあげる必要があります。また、DLL名が多少違っていたりする場合には、元のファイルをコピーして名前を変えると動いたりします。

*1:自分でbuildすることも可能ですが茨の道です。。。

明けましておめでとうございます。

2013年、今年もまたよろしくお願いします。去年は一月に1entryも書けてませんが、マイペースに続けていけたらと思います。
UIEKKで既に1年以上働いていますが、楽しく働かせて頂いています。社内のプロセスも積極的に改善していければ、もっと居心地がよくなるのではないかと。
去年の年初のentryを見てみたら、Haskellを勉強しようなんて書いてたんですね。仕事でもHaskellを使ったりして、目標は達成できてました。しかし、まだまだちゃんと理解できていないことが多いのでHaskellはもっと勉強しないとダメですね。
それ以外では、もっとサーバの運用技術も調べていこうと思っています。

Haskell on Heroku

HaskellのScottyで Webサーバを書いていたのですが、Herokuへのdeployがうまくできたので手順をメモしておきます。yesod on heroku 等は結構検索で引っかかるんですが、新旧が色々と混じっているので現時点でのまとめになります。
環境は、MacOS MountainLionです。

まず前提として、HerokuでHaskellのWebサーバを動かすには、binaryを手元で生成して上げてdeploy後にキックする形になります。そのため、Herokuで使っている Ubuntuの10.04 LTS 上でbinaryをbuildするのが一番確実です。それさえ準備できれば、後はnode.jsを動かすのと同じような形で動かすことができます。

Webサーバの起動ファイルを用意する

binaryを生成する際の注意点としては、ライブラリのインストールを別途行うことはできないのでstatic linkするようにbuildする必要があります。Haskellでしたら、cabalファイルに「ghc-options: -static」を追加して上げるのが良いです。
次に以下のコマンドでpackage.jsonを生成します。

$ echo '{ "name": "first-yesod", "version": "0.0.1", "dependencies": {} }' >> package.json

最後に、ProcFileを以下の内容で準備します*1。以下のコマンドでdeployしたWebサーバが起動するので、listenするport番号は起動時に $PORTで指定できるようにしておく必要があります。

web: ./dist/build/my-server/my-server --port $PORT

ここまで準備ができたら、一旦gitリポジトリへコミットしておきます。

Vagrantを使って build環境を構築する。

http://vagrantup.com/v1/docs/getting-started/index.html
このページを参考に、VirtualBoxVagrantをインストールします。
その後、別のフォルダへ移動し以下のコマンドを実行します。

$ git clone git@bitbucket.org:puffnfresh/vagrant-haskell-heroku.git
$ cd vagrant-haskell-heroku
$ vargant up
$ vargant ssh

vargant upで結構な時間がかかりますが、問題なく終わればこれでVMsshで接続した状態になります。このVMはUbuntu10.04 LTSに、ghc7.4.1 とcabal1.14.0 が既にインストールした状態になっています。gitコマンドやheroku toolbeltは未インストールなので、以下のコマンドでインストールしてあげます。

$ sudo apt-get install git-core
$ wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh
$ ssh-keygen -t rsa
$ heroku keys:add
$ heroku login

最後にherokuにnode.jsようのappを生成します。既に作成済みの場合には不要です。

$ heroku create --stack cedar

以上で、環境構築は完了です。

herokuへdeployする

これまでの手順で環境構築はできたので、最後にbuildしてdeployしてあげます。vargant に接続したままで以下のように実行します。

$ git clone git@repository:my-server.git
$ cd my-server
$ git checkout -b deploy
$ cabal update
$ cabal install
$ git add -f dist/build/my-server/my-server
$ git commit -m "Deploy `date`"
$ git remote add heroku git@heroku.com:my-server.git
$ git push -f heroku deploy:master

これで、deployが完了です。

$ heroku open

このコマンドで、実行結果を確認できます。エラーが表示された場合には、以下のコマンドでログを確認しましょう。

$ heroku logs

*1:my-server が今回作成するアプリ名です

iPhone用に PCRE (Perl-compatible regular expressions) をbuild

PCREを使うことになったので、arm向けの buildコマンドのメモ。
10/03: armv7s版のライブラリもbuildするように手順を変更しました。

前提となる環境が更新されていて、以下の通り。

  • OS: MacOSX 10.8 Mountain Lion
  • コンパイラ: XCode 4.5 *1
  • PCRE は ver 8.31
  • Cのライブラリ(libpcre.a)しか使わないので、libc++ or libstdc++への依存はなし

build手順は以下のコマンドを順に実行すればできました。

$ curl -O ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.31.tar.bz2
$ tar jxvf pcre-8.31.tar.bz2
$ cd pcre-8.31/
$ export SDK_ROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer
$ ./configure CC="${SDK_ROOT}/usr/bin/gcc" CPP="${SDK_ROOT}/usr/bin/gcc -E" CFLAGS="-arch armv7 -isysroot ${SDK_ROOT}/SDKs/iPhoneOS6.0.sdk" --host=arm
$ make
$ mv .libs .libs_arm7
$ ./configure CC="${SDK_ROOT}/usr/bin/gcc" CPP="${SDK_ROOT}/usr/bin/gcc -E" CFLAGS="-arch armv7s -isysroot ${SDK_ROOT}/SDKs/iPhoneOS6.0.sdk" --host=arm
$ make
$ mv .libs .libs_arm7s
$ ./configure CC='gcc -arch i386' CPP='gcc -E'
$ make
$ mv .libs .libs_i386
$ xcrun -sdk iphoneos lipo -create -arch armv7 .libs_arm7/libpcre.a -arch armv7s .libs_arm7s/libpcre.a -arch i386 .libs_i386/libpcre.a -output libpcre.a

最後に、カレントディレクトリにある pcre.h と libpcre.a をコピーすればPCREが使えるようになります。

*1:XCode の Command Line Tools はインストールしておいて下さい。

iPhone用に boostのユニバーサルスタティックライブラリを作成

色々と調べたけど、現状の最新環境でうまく行かなかったので、最終的に作成した手順をまとめておくことにしました。

前提として、以下の環境でユニバーサルスタティックライブラリを作成

  • OS: MacOSX 10.8 Mountain Lion
  • コンパイラ: XCode 4.4.1の clang
    • さらに、libc++ を使用する
  • boost: ver 1.50.0
    • ビルド対象ライブラリ: regex, thread(特に指定していないため、ひと通りのライブラリが作成されますが、この手順では arm版のsignalだけbuildエラーになるため、そこは諦めました。。。)

それでは、buildの手順です。

何はともあれ、boost_1_50_0.tar.bz2 をdownloadしてきて解凍します。

$ tar zxf boost_1_50_0.tar.bz2
$ cd boost_1_50_0

次に、boostのbuildのキモになる、bootstrapとbjamを実行します。
今回は、ユニバーサルスタティックライブラリを作成するのが目的ですが、一回のbuildで作成する方法が分からなかったため、arm版とi386版を別々にbuildしてあとからユニバーサルバイナリを作成するという手順になっています。*1

$ ./bootstrap.sh --with-toolset=clang
$ ./b2 toolset=clang cxxflags="-std=c++11 -stdlib=libc++" linkflags="-stdlib=libc++" cflags="-std=c99 -arch armv7 -fvisibility=default -miphoneos-version-min=5.0" architecture=arm target-os=iphone link=static threading=multi define=_LITTLE_ENDIAN include=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/include/
$ mv stage/lib stage/lib_arm
$ ./b2 toolset=clang cxxflags="-std=c++11 -stdlib=libc++" linkflags="-stdlib=libc++ -arch i386" cflags="-std=c99 -fvisibility=default -arch i386" architecture=x86 address-model=32 target-os=iphone link=static threading=multi include=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/usr/include
$ mv stage/lib stage/lib_i386
$ mkdir stage/lib
$ lipo -create -output stage/lib/libboost_thread.a -arch armv7 stage/lib_arm/libboost_thread.a -arch i386 stage/lib_i386/libboost_thread.a 
$ lipo -create -output stage/lib/libboost_regex.a -arch armv7 stage/lib_arm/libboost_regex.a -arch i386 stage/lib_i386/libboost_regex.a 

以上で、完了です。stage/lib 以下にユニバーサルスタティックライブラリが作られます。
手順としては、基本に忠実に bootstrap.sh→b2*2×2 でライブラリを生成→lipo でユニバーサルライブラリ生成 となっています。最後のlipoコマンドで、ライブラリ名を変えていけばそれぞれのライブラリのユニバーサルバイナリが作成できます。

*1:もっと、うまいやり方があれば教えて下さい。

*2:いつの間にか bjamが新しくなってたんですね。

MacOSXの Homebrewで最新の GCC 4.7.0 をインストール

普通にはbrewではgccをインストールできません。しかし、XCodeでインストールされるgccは Ver.4.2と古いので C++11標準の機能はまったく使えません。たぶん、clangを使えということなんでしょうけど、gccを使う必要があったのでインストール方法を調べました。

Homebrewの標準の formulaにはgccがないのですが、Homebrew-alt というプロジェクトで標準でサポートされていないモジュールをカバーしているようです。しかし、ちょっと前から dupsやversionsなどの複数のプロジェクトに分割されたようです。
そんな訳で、gccの最新版は homebrew-bupsの下にあるので、以下のコマンドでインストールできます。自分の環境では、gccがないため「--use-llvm」のオプションが必要でした。

$ brew install https://raw.github.com/Homebrew/homebrew-dupes/master/gcc.rb --enable-all-languages --use-llvm

これで、gccがbuildされ*1、インストールされます。
後は、/usr/bin/gcc 等のシンボリックリンクllvm版を向いているので、今回インストールした版に変更して完了です。

$ sudo ln -sf /usr/local/bin/gcc-4.7 /usr/bin/gcc
$ sudo ln -sf /usr/local/bin/g++-4.7 /usr/bin/g++
$ sudo ln -sf /usr/local/bin/g++-4.7 /usr/bin/c++
$ sudo ln -sf /usr/local/bin/gcc-4.7 /usr/bin/cc


検索しても古い情報がひっかかるので、現状の最新情報をまとめておきました。

*1:結構、時間がかかります。