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では型は基本的に明示するものということなんですかね?型推論はそれほど強くないのかな?
今まで Haskell や C# では、特に明示しなくても推論されていたので、違いが気になりました。
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のインストール
PostgreSQLはWindows版のインストーラが用意されているので、それを使ってインストールすれば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
以上で、完了です。お疲れ様でした。
*1:自分でbuildすることも可能ですが茨の道です。。。
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
このページを参考に、VirtualBoxとVagrantをインストールします。
その後、別のフォルダへ移動し以下のコマンドを実行します。
$ git clone git@bitbucket.org:puffnfresh/vagrant-haskell-heroku.git $ cd vagrant-haskell-heroku $ vargant up $ vargant ssh
vargant upで結構な時間がかかりますが、問題なく終わればこれでVMへsshで接続した状態になります。この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が使えるようになります。
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コマンドで、ライブラリ名を変えていけばそれぞれのライブラリのユニバーサルバイナリが作成できます。
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:結構、時間がかかります。