先月.NETのクロスプラットフォーム化が発表されました 。そのうちMacとLinuxに移植されるそうですが、これにはXamarinとMonoが大きな役割を担っているようです。Xamarin の名前も最近よく聞くようになりました。XamarinではC#でiOSとAndroidのクロスプラットフォームの開発ができますが、F#でもアプリを書けるようです。F#はOCamlやHaskellの影響を受けている関数型言語です。オブジェクト指向的な書き方もできるみたいで、以前から興味があったのですが、良い機会なのでDocker開発環境をつくって勉強してみようと思います。
Dockerfile masato/docker-fsharp はいつもの様にphusion/baseimage を使ってF#の開発環境のイメージをビルドしました。GitHubのリポジトリはmasato/docker-fsharp です。
~/docker_apps/docker-fsharp/Dockerfile ROM phusion/baseimage:0.9.15 MAINTAINER Masato Shimizu <ma6ato@gmail.com> ENV HOME /root RUN /etc/my_init.d/00_regen_ssh_host_keys.sh RUN /usr/sbin/enable_insecure_key ENV LANG ja_JP.UTF-8 RUN locale-gen $LANG && update-locale $LANG && \ ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive \ apt-get install -y python emacs24-nox emacs24-el git byobu wget curl unzip tree elinks RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" > /etc/apt/sources.list.d/mono-xamarin.list && \ apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y mono-devel fsharp mono-vbnc nuget RUN mozroots --machine --import --sync --quiet RUN update-alternatives --set editor /usr/bin/vim.basic ENV USERNAME docker ENV HOME /home/${USERNAME} RUN useradd -m -d ${HOME} -s /bin/bash ${USERNAME} && \ echo "${USERNAME} :${USERNAME} " | chpasswd && \ mkdir ${HOME} /.ssh ${HOME} /tmp && \ chmod 700 ${HOME} /.ssh && \ cp /root/.ssh/authorized_keys ${HOME} /.ssh && \ chmod 600 ${HOME} /.ssh/authorized_keys && \ chown -R ${USERNAME} :${USERNAME} ${HOME} /.ssh && \ echo "export LANG=ja_JP.UTF-8" >> ${HOME} /.profile && \ echo "docker ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers ADD dotfiles ${HOME} RUN chown -R ${USERNAME} :${USERNAME} ${HOME} RUN curl -fsSkL https://raw.github.com/cask/cask/master/go | python && \ echo export PATH='${HOME}/.cask/bin:$PATH' >> ${HOME} /.profile && \ /bin/bash -c 'source ${HOME}/.profile && cd ${HOME}/.emacs.d && cask install' USER root ENV HOME /root WORKDIR /root CMD ["/sbin/my_init" ] RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
Emacs Cask ファイルにfsharp-mode を追加します。
~/docker_apps/docker-fsharp/dotfiles/.emacs.d/Cask ... ;; fsharp (depends-on "fsharp-mode") ...
initsディレクトリにfsharp-modeの設定を書きます。
~/docker_apps/docker-fsharp/dotfiles/.emacs.d/inits/12-fsharp-mode.el
Dockerコンテナの起動 使い捨てのコンテナを起動します。dockerユーザーにスイッチして作業ディレクトリを作成します。
$ docker run -it --rm masato/docker-fsharp /sbin/my_init bash $ su - docker $ mkdir fsharp_apps $ cd !$
バージョンの確認 monoのバージョンは3.10.0です。
$ mono --version Mono JIT compiler version 3.10.0 (tarball Wed Nov 5 12:50:04 UTC 2014) Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com TLS: __thread SIGSEGV: altstack Notifications: epoll Architecture: amd64 Disabled: none Misc: softdebug LLVM: supported, not enabled. GC: sgen
F#のバージョンは3.1です。
$ fsharpi F Freely distributed under the Apache 2.0 Open Source License For help type >
コンパイルして実行する Hello World
を作成します。
~/fsharp_apps/hello_world.fs [<EntryPoint>] let main argv = printfn "ハロー、ワールド" 0
コンパイルします。
$ fsharpc hello_world.fs F Freely distributed under the Apache 2.0 Open Source License
コンパイルされたexeファイルには実行権限がついていますが、そのまま実行するとエラーになります。
$ ./hello_world.exe -su: ./hello_world.exe: cannot execute binary file: Exec format error
exeファイルを実行する場合は、monoコマンドを使います。
$ mono hello_world.exe ハロー、ワールド
インタプリタを実行する fsharpiコマンドでインタプリタを開始します。
$ fsharpi F Freely distributed under the Apache 2.0 Open Source License For help type >
リテラルを入力した後は、セミコロンを2つ入力してEnterキーで実行します。
> "hello world" ;; val it : string = "hello world" > 1 + 2;; val it : int = 3
#help;;
で表示されるように、インタプリタを終了する場合は#quit;;
を実行します。
> F F See 'fsharpi --help' for options > - Exit...