Docker で F# アプリケーションを作成
Microsoft による .NET Core の公式 Docker イメージを使って、単純な F# のコンソールアプリケーションを作成してみました。
今回のソースは http://github.com/fits/try_samples/tree/master/blog/20170619/
(1) Docker コンテナの実行
まずは .NET Core の Docker コンテナを実行しておきます。
.NET Core コンテナの実行
$ docker run -it --rm microsoft/dotnet /bin/bash root@・・・:/#
現時点では 1.1.2-sdk が latest となっており、デフォルトで netcoreapp1.1
のアプリケーションを作成する事になります。
(2) F# コンソールプロジェクトの作成
.NET Core SDK では dotnet
コマンド (.NET Command Line Tools) を使ってアプリケーションを開発できます。
dotnet new
コマンドで様々なプロジェクトの雛型を作成でき、デフォルトでは以下のようなプロジェクトに対応しています。
プロジェクトの雛型一覧
root@・・・# dotnet new -all ・・・ Templates Short Name Language Tags ----------------------------------------------------------------------- Console Application console [C#], F# Common/Console Class library classlib [C#], F# Common/Library Unit Test Project mstest [C#], F# Test/MSTest xUnit Test Project xunit [C#], F# Test/xUnit ASP.NET Core Empty web [C#] Web/Empty ASP.NET Core Web App mvc [C#], F# Web/MVC ASP.NET Core Web API webapi [C#] Web/WebAPI Nuget Config nugetconfig Config Web Config webconfig Config Solution File sln Solution ・・・
今回は F# のコンソールアプリケーションを作成します。
適当なディレクトリを作成・移動し、dotnet new console
を実行します。
F# の場合は -lang
オプションで指定します。 (デフォルトは C#)
F# コンソールプロジェクトの作成
root@・・・# mkdir sample root@・・・# cd sample root@・・・# dotnet new console -lang F#
以下のファイルが生成されました。
Program.fs
open System [<EntryPoint>] let main argv = printfn "Hello World from F#!" 0 // return an integer exit code
sample.fsproj
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp1.1</TargetFramework> </PropertyGroup> <ItemGroup> <Compile Include="Program.fs" /> </ItemGroup> <ItemGroup> <PackageReference Include="FSharp.Core" Version="4.1.*" /> <PackageReference Include="FSharp.NET.Sdk" Version="1.0.*" PrivateAssets="All" /> </ItemGroup> </Project>
(3) ビルドと実行
とりあえず、このままビルドして実行してみます。
まずは dotnet restore
を実行してプロジェクトの依存関係を復元します。
これにより依存関係などが定義された obj/project.assets.json
ファイルが作られます。
リストア
root@・・・# dotnet restore ・・・ Installing FSharp.Compiler.Tools 4.1.17. Installing FSharp.NET.Sdk 1.0.5. Installing FSharp.Core 4.1.17. ・・・ Installed: 3 package(s) to /sample/sample.fsproj
ビルドは dotnet build
で行います。
なお、dotnet build しなくても dotnet run すればビルドも実施してくれるようです。
ビルド
root@・・・# dotnet build ・・・ Build succeeded. 0 Warning(s) 0 Error(s)
dotnet run
で実行します。
実行
root@・・・# dotnet run Hello World from F#!
(4) Chiron パッケージの追加
次に、Chiron という F# で JSON を処理するためのパッケージを使ってみます。
依存パッケージは dotnet add package <パッケージ名>
で追加できますが、(現時点で)デフォルトの Chiron 6.2.1 を追加しようとすると以下のようにエラーとなりました。
Chiron パッケージ(6.2.1)追加 - 失敗
root@・・・# dotnet add package chiron ・・・ log : Installing Chiron 6.2.1. error: Package Chiron 6.2.1 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1). Package Chiron 6.2.1 supports: error: - net40 (.NETFramework,Version=v4.0) error: - portable-net45+win8+wp8+wpa81 (.NETPortable,Version=v0.0,Profile=Profile259) ・・・ error: One or more packages are incompatible with .NETCoreApp,Version=v1.1. error: Package 'chiron' is incompatible with 'all' frameworks in project '/sample/sample.fsproj'.
netcoreapp1.1
(.fsproj の TargetFramework で設定) を Chiron 6.2.1 がサポートしてない事が原因のようです。
nuget の Chiron のページ を見てみると .NETStandard 1.6 に対応したバージョン 7.0.0-alpha-170410 がありました。
netcoreapp1.1 は .NETStandard 1.6 をサポートしているので、このバージョンなら使えそうです。
add package では -v
オプションでバージョンを指定できるので、以下のようにバージョンを指定して Chiron を追加します。
Chiron パッケージ(7.0.0-alpha-170410)追加 - 成功
root@・・・# dotnet add package chiron -v 7.0.0-alpha-170410 ・・・ log : Installing FParsecCS 1.0.3-alpha-170404. log : Installing FParsec 1.0.3-alpha-170404. log : Installing Chiron 7.0.0-alpha-170410. info : Package 'chiron' is compatible with all the specified frameworks in project '/sample/sample.fsproj'. info : PackageReference for package 'chiron' version '7.0.0-alpha-170410' added to file '/sample/sample.fsproj'.
今度は成功し、.fsproj は以下のようになりました。
sample.fsproj (Chiron 追加後)
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp1.1</TargetFramework> </PropertyGroup> <ItemGroup> <Compile Include="Program.fs" /> </ItemGroup> <ItemGroup> <PackageReference Include="chiron" Version="7.0.0-alpha-170410" /> <PackageReference Include="FSharp.Core" Version="4.1.*" /> <PackageReference Include="FSharp.NET.Sdk" Version="1.0.*" PrivateAssets="All" /> </ItemGroup> </Project>
(5) Chiron サンプルアプリケーションの実装
動作確認のため Chiron を使った単純な処理を実装してみました。 (Chiron 7 ではモジュール構成等が変わっているようでした)
Program.fs
open System open Chiron.Inference [<EntryPoint>] let main argv = let d = Map ["a", 123] let res = Json.serialize d printfn "json = %s" res 0
(6) Chiron サンプルアプリケーションのビルドと実行
(3) と同様にリストアしてから実行します。
リストア
root@・・・# dotnet restore Restoring packages for /sample/sample.fsproj... ・・・
ビルド
root@・・・# dotnet build ・・・ Build succeeded. 0 Warning(s) 0 Error(s)
実行
root@・・・# dotnet run json = {"a":123}