apeescape2.com
  • メイン
  • ツールとチュートリアル
  • エンジニアリング管理
  • データサイエンスとデータベース
  • 投資家と資金調達
バックエンド

F#チュートリアル:フルスタックF#アプリを構築する方法

近年、関数型プログラミングは、特に厳密で生産的なパラダイムとしての評判を得ています。関数型プログラミング言語がプログラマーコミュニティ内で注目を集めているだけでなく、多くの大企業も関数型プログラミング言語を使用して商業上の問題を解決し始めています。

たとえば、ウォルマートは使用を開始しました Clojure 、チェックアウトインフラストラクチャ用のJVMベースの機能的なLisp方言。大規模なeコマースプラットフォーム(現在はウォルマートが所有)であるJet.comは、F#を使用してほとんどのマイクロサービスを構築しています。自己勘定取引会社のジェーンストリートは、主にOCamlを使用してアルゴリズムを構築しています。

今日は探検します F#プログラミング 。 F#は、その柔軟性、強力な.NET統合、および利用可能なツールの高品質により、採用が増加している関数型プログラミング言語の1つです。このF#チュートリアルの目的のために、フロントエンドとバックエンドの両方にF#のみを使用して、単純なWebサーバーと関連するモバイルアプリを構築します。



F#を選択する理由とF#の用途

今日のプロジェクトでは、F#のみを使用します。選択する言語としてF#を選択する理由はいくつかあります。

  • .NET統合: F#は、他の.NETワールドと非常に緊密に統合されているため、幅広いプログラミングタスクを解決するために、十分にサポートされ、完全に文書化されたライブラリの大規模なエコシステムにすぐにアクセスできます。
  • 簡潔: F#は、その強力な型推論システムと簡潔な構文により、非常に簡潔です。多くの場合、プログラミングタスクは、C#やJavaよりもF#を使用してはるかにエレガントに解決できます。 F#コードは、比較すると非常に合理化されているように見えます。
  • 開発者ツール: F#は、.NETエコシステムに最適なIDEの1つであるVisualStudioの強力な統合を楽しんでいます。 Windows以外のプラットフォームで作業している場合は、VisualStudioコードに豊富なプラグインがあります。これらのツールは、F#でのプログラミングを非常に生産的にします。

F#を使用する利点については続けることができますが、それ以上の苦労はせずに、詳しく見ていきましょう。

F#チュートリアルの背後にあるアイデア

米国では、一般的なことわざがあります: 「どこか5時です」 。

世界の一部の地域では、午後5時が、飲み物や伝統的なお茶を飲むことが社会的に受け入れられる最も早い時間です。

ハッキングされたクレジットカード番号cvv

今日は、このコンセプトに基づいてアプリケーションを構築します。いつでもさまざまなタイムゾーンを検索し、5時の場所を見つけて、その情報をユーザーに提供するアプリケーションを構築します。

バックエンド

Webサーバーのセットアップ

まず、タイムゾーン検索機能を実行するバックエンドサービスを作成します。 Suave.IOを使用してJSONAPIを構築します。

F#チュートリアルの図:Webサーバーのセットアップ

Smooth.IO は、軽量のWebサーバーを備えた直感的なWebフレームワークであり、単純なWebアプリを非常に迅速にコーディングできます。

まず、Visual Studioに移動して、新しいF#コンソールアプリケーションプロジェクトを開始します。このオプションを使用できない場合は、Visual Studioインストーラーを使用してF#機能をインストールする必要があります。プロジェクトに「FivePM」という名前を付けます。アプリケーションが作成されると、次のように表示されます。

[] let main argv = printfn '%A' argv 0 // return an integer exit code

これは、引数を出力し、ステータスコード0で終了する非常に単純なスターターコードです。printステートメントを自由に変更して、コードのさまざまな関数を試してみてください。 「%A」フォーマッタは、渡した型の文字列表現を出力する特別なフォーマッタであるため、整数、浮動小数点数、または複合型を自由に出力できます。基本的な構文に慣れたら、Suaveをインストールします。

Suaveをインストールする最も簡単な方法は、NuGetパッケージマネージャーを使用することです。 [プロジェクト]-> [NuGetパッケージの管理]に移動し、[参照]タブをクリックします。 Suaveを検索し、[インストール]をクリックします。インストールするパッケージを受け入れると、すべての設定が完了します。これでprogram.fs画面に戻り、サーバーの構築を開始する準備が整いました。

Suaveの使用を開始するには、最初にパッケージをインポートする必要があります。プログラムの上部に、次のステートメントを入力します。

open Suave open Suave.Operators open Suave.Filters open Suave.Successful

これにより、基本的なWebサーバーの構築に必要な基本的なパッケージがインポートされます。次に、メインのコードを次のコードに置き換えます。これは、単純なアプリを定義し、ポート8080で提供します。

[] let main argv = // Define the port where you want to serve. We'll hardcode this for now. let port = 8080 // create an app config with the port let cfg = { defaultConfig with bindings = [ HttpBinding.createSimple HTTP '0.0.0.0' port]} // We'll define a single GET route at the / endpoint that returns 'Hello World' let app = choose [ GET >=> choose [ path '/' >=> request (fun _ -> OK 'Hello World!')] ] // Now we start the server startWebServer cfg app 0

F#構文やSuaveのルートハンドラーの定義方法に慣れていない場合でも、コードは非常に単純に見えるはずです。コードはかなり読みやすいはずです。基本的に、Webアプリは200ステータスと「HelloWorld!」で返されます。 「/」ルートでGETリクエストがヒットしたときの文字列。先に進み、アプリケーション(Visual StudioではF5)を実行し、localhost:8080に移動すると、「HelloWorld!」と表示されます。ブラウザウィンドウで。

サーバーコードのリファクタリング

これでWebサーバーができました!残念ながら、それはそれほど多くのことをしません-それで、それにいくつかの機能を与えましょう!まず、Webサーバーの機能を別の場所に移動して、Webサーバーを気にせずにいくつかの機能を構築しましょう(後でWebサーバーに接続します)。このように別の関数を定義します。

// We'll use argv later :) let runWebServer argv = // Define the port where you want to serve. We'll hardcode this for now. let port = 8080 // create an app config with the port let cfg = { defaultConfig with bindings = [ HttpBinding.createSimple HTTP '0.0.0.0' port]} // We'll define a single GET route at the / endpoint that returns 'Hello World' let app = choose [ GET >=> choose [ path '/' >=> request (fun _ -> OK 'Hello World!')] ] // Now we start the server startWebServer cfg app

次に、main関数を次のように変更し、正しく実行されたことを確認します。

[] let main argv = runWebServer argv 0

F5を押すと、「HelloWorld!」サーバーは以前と同じように機能するはずです。

タイムゾーンの取得

それでは、5時のタイムゾーンを決定する機能を構築しましょう。すべてのタイムゾーンを反復処理し、午後5時に最も近いタイムゾーンを決定するコードを記述します。

タイムゾーンの取得の図

さらに、午後5時に非常に近いが、少し前(たとえば、午後4時58分)のタイムゾーンを返すことは実際には望んでいません。このデモンストレーションの目的では、5時より前にすることはできないという前提があるためです。 :00 pm、ただし閉店。

タイムゾーンのリストを取得することから始めましょう。 F#では、C#と非常によく統合されているため、これは非常に簡単です。上部に「オープンシステム」を追加し、F#アプリケーションを次のように変更します。

[] let main argv = // This gets all the time zones into a List-like object let tzs = TimeZoneInfo.GetSystemTimeZones() // Now we iterate through the list and print out the names of the timezones for tz in tzs do printfn '%s' tz.DisplayName 0

アプリケーションを実行すると、コンソールにすべてのタイムゾーン、それらのオフセット、およびそれらの表示名のリストが表示されます。

カスタムタイプの作成と使用

タイムゾーンのリストができたので、UTCオフセット、現地時間、現地時間の午後5時からの距離などの情報を含む、より便利なカスタムデータ型に変換できます。 、など。そのために、メイン関数のすぐ上にカスタムタイプを定義しましょう。

type TZInfo = {tzName: string; minDiff: float; localTime: string; utcOffset: float}

これで、最後のステップで取得したタイムゾーン情報をこのTZInfoオブジェクトのリストに変換できます。このようにメイン関数を変更します。

asana vs wrike vs trello
[] let main argv = // This gets all the time zones into a List-like object let tzs = TimeZoneInfo.GetSystemTimeZones() // List comprehension + type inference allows us to easily perform conversions let tzList = [ for tz in tzs do // convert the current time to the local time zone let localTz = TimeZoneInfo.ConvertTime(DateTime.Now, tz) // Get the datetime object if it was 5:00pm let fivePM = DateTime(localTz.Year, localTz.Month, localTz.Day, 17, 0, 0) // Get the difference between now local time and 5:00pm local time. let minDifference = (localTz - fivePM).TotalMinutes yield { tzName=tz.StandardName; minDiff=minDifference; localTime=localTz.ToString('hh:mm tt'); utcOffset=tz.BaseUtcOffset.TotalHours; } ] printfn '%A' tzList.Head 0

また、日付変更線の標準時のtzInfoオブジェクトが画面に印刷されているはずです。

並べ替えとフィルタリングとパイピング、オーマイ!

これらのtzInfoオブジェクトのリストができたので、これらのオブジェクトをフィルタリングおよびソートして、1)午後5時以降および2)1)のタイムゾーンの午後5時に最も近いタイムゾーンを見つけることができます。次のようにメイン関数を変更します。

[] let main argv = // This gets all the time zones into a List-like object let tzs = TimeZoneInfo.GetSystemTimeZones() // List comprehension + type inference allows us to easily perform conversions let tzList = [ for tz in tzs do // convert the current time to the local time zone let localTz = TimeZoneInfo.ConvertTime(DateTime.Now, tz) // Get the datetime object if it was 5:00pm let fivePM = DateTime(localTz.Year, localTz.Month, localTz.Day, 17, 0, 0) // Get the difference between now local time and 5:00pm local time. let minDifference = (localTz - fivePM).TotalMinutes yield { tzName=tz.StandardName; minDiff=minDifference; localTime=localTz.ToString('hh:mm tt'); utcOffset=tz.BaseUtcOffset.TotalHours; } ] // We use the pipe operator to chain functiona calls together let closest = tzList // filter so that we only get tz after 5pm |> List.filter (fun (i:TZInfo) -> i.minDiff >= 0.0) // sort by minDiff |> List.sortBy (fun (i:TZInfo) -> i.minDiff) // Get the first item |> List.head printfn '%A' closest

これで、探しているタイムゾーンができました。

タイムゾーンゲッターを独自の機能にリファクタリングする

それでは、後で使用できるように、コードを独自の関数にリファクタリングしてみましょう。このように関数を定義します。

// the function takes uint as input, and we represent that as '()' let getClosest () = // This gets all the time zones into a List-like object let tzs = TimeZoneInfo.GetSystemTimeZones() // List comprehension + type inference allows us to easily perform conversions let tzList = [ for tz in tzs do // convert the current time to the local time zone let localTz = TimeZoneInfo.ConvertTime(DateTime.Now, tz) // Get the datetime object if it was 5:00pm let fivePM = DateTime(localTz.Year, localTz.Month, localTz.Day, 17, 0, 0) // Get the difference between now local time and 5:00pm local time. let minDifference = (localTz - fivePM).TotalMinutes yield { tzName=tz.StandardName; minDiff=minDifference; localTime=localTz.ToString('hh:mm tt'); utcOffset=tz.BaseUtcOffset.TotalHours; } ] // We use the pipe operator to chain function calls together tzList // filter so that we only get tz after 5pm |> List.filter (fun (i:TZInfo) -> i.minDiff >= 0.0) // sort by minDiff |> List.sortBy (fun (i:TZInfo) -> i.minDiff) // Get the first item |> List.head And our main function can just be: [] let main argv = printfn '%A' <| getClosest() 0

コードを実行すると、前と同じ出力が表示されます。

戻りデータをエンコードするJSON

タイムゾーンデータを取得できるようになったので、情報をJSONに変換し、アプリケーションを介して提供できます。 NewtonSoftのJSON.NETパッケージのおかげで、これは非常に簡単です。 NuGetパッケージマネージャーに戻り、Newtonsoft.Jsonを見つけて、パッケージをインストールします。ここで、Program.fsに戻り、メイン関数に小さな変更を加えます。

[] let main argv = printfn '%s' <| JsonConvert.SerializeObject(getClosest()) 0

今すぐコードを実行すると、TZInfoオブジェクトの代わりに、JSONがコンソールに出力されます。

タイムゾーン情報をJSONAPIに接続する

これをJSONAPIに接続するのは非常に簡単です。 runWebServer関数に次の変更を加えるだけです。

// We'll use argv later :) let runWebServer argv = // Define the port where you want to serve. We'll hardcode this for now. let port = 8080 // create an app config with the port let cfg = { defaultConfig with bindings = [ HttpBinding.createSimple HTTP '0.0.0.0' port]} // We'll define a single GET route at the / endpoint that returns 'Hello World' let app = choose [ GET >=> choose [ // We are getting the closest time zone, converting it to JSON, then setting the MimeType path '/' >=> request (fun _ -> OK => setMimeType 'application/json; charset=utf-8' ] ] // Now we start the server startWebServer cfg app

アプリケーションを実行し、localhost:8080に移動します。ブラウザウィンドウにJSONが表示されます。

サーバーのデプロイ

JSON APIサーバーができたので、インターネット上でアクセスできるようにデプロイできます。このアプリケーションを展開する最も簡単な方法の1つは、マネージドIISサービスとして理解できるMicrosoftAzureのAppServiceを使用することです。 Azure App Serviceにデプロイするには、https://portal.azure.comにアクセスし、AppServiceにアクセスします。新しいアプリを作成し、ポータルのデプロイメントセンターに移動します。ポータルは初めての場合は少々圧倒される可能性があるため、問題が発生した場合は、AppServiceの使用に関する多くのチュートリアルの1つを参照してください。

展開のためのさまざまなオプションが表示されます。好きなものを使用できますが、簡単にするために、FTPオプションを使用できます。

Appサービスは、アプリケーションのルートでweb.configファイルを探して、アプリケーションの実行方法を認識します。 Webサーバーは不可欠なコンソールアプリケーションであるため、HttpPlatformHandlerを使用してアプリケーションを公開し、IISサーバーと統合できます。 Visual Studioで、XMLファイルをプロジェクトに追加し、web.configという名前を付けます。次のXMLで入力します。

let runWebServer (argv:string[]) = // Define the port where you want to serve. We'll hardcode this for now. let port = if argv.Length = 0 then 8080 else (int argv.[0])

デプロイメントセンターから取得した資格情報を使用してFTPサーバーに接続します(FTPオプションをクリックする必要があります)。 web.configをアプリサービスFTPサイトのwwwrootフォルダーに移動します。

ここで、アプリケーションをビルドして公開したいと思いますが、その前に、サーバーコードに小さな変更を加える必要があります。 runServer関数に移動し、最初の3行を次のように変更します。

*.azurewebsites.net

これにより、アプリケーションは渡された引数を確認し、ポートを8080にハードコーディングするのではなく、最初の引数をポート番号として使用できます。Web構成では、%HTTP_PLATFORM_PORT%を最初の引数として渡すため、設定する必要があります。

リリースモードでアプリケーションをビルドし、アプリケーションを公開し、公開されたフォルダーをwwwrootにコピーします。アプリケーションを再起動すると、JSONAPIの結果が [] type MainActivity () = inherit Activity () let mutable count:int = 1 override this.OnCreate (bundle) = base.OnCreate (bundle) // Set our view from the 'main' layout resource this.SetContentView (Resources.Layout.Main) // Get our button from the layout resource, and attach an event to it let button = this.FindViewById(Resources.Id.myButton) button.Click.Add (fun args -> button.Text <- sprintf '%d clicks!' count count <- count + 1 ) に表示されます。地点。

これで、アプリケーションがデプロイされました。

破産第11章はどういう意味ですか

フロントエンド

F#フロントエンドの図

サーバーがデプロイされたので、フロントエンドを構築できます。フロントエンドでは、を使用してAndroidアプリケーションを構築します Xamarin およびF#。このスタックは、バックエンド環境と同様に、VisualStudioとの緊密な統合を楽しんでいます。もちろん、F#エコシステムはかなりの数のフロントエンド開発オプション(WebSharper、Fable / Elmish、Xamarin.iOS、DotLiquidなど)をサポートしていますが、簡潔にするために、この投稿ではXamarin.Androidのみを使用して開発します。将来の投稿のためにそれら。

セットアップ

Androidアプリをセットアップするには、新しいプロジェクトを開始し、XamarinAndroidオプションを選択します。 Android開発ツールがインストールされていることを確認してください。プロジェクトが設定されると、メインコードファイルに次のようなものが表示されます。

It's 5PM Somewhere! 5PM Finder

これは、F#AndroidXamarinのスターターコードです。コードは現在、ボタンがクリックされた回数を追跡し、現在のカウント値を表示します。 F5キーを押してエミュレーターを起動し、アプリケーションをデバッグモードで起動すると、動作することがわかります。

UIコンポーネントの追加

いくつかのUIコンポーネントを追加して、より便利にしましょう。リソース/レイアウトを開き、Main.axmlに移動します。

メインのアクティビティレイアウトが視覚的に表示されます。要素をクリックすると、さまざまなUI要素を編集できます。ツールボックスに移動し、追加する要素を選択することで、要素を追加できます。ボタンの名前を変更し、ボタンの下にtextViewを追加します。 AXMLのXML表現は次のようになります。

base.OnCreate (bundle) // Set our view from the 'main' layout resource this.SetContentView (Resources.Layout.Main) // Get our button from the layout resource, and attach an event to it let button = this.FindViewById(Resources.Id.myButton) let txtView = this.FindViewById(Resources.Id.textView1); button.Click.Add (fun args -> let webClient = new WebClient() txtView.Text <- webClient.DownloadString('https://fivepm.azurewebsites.net/') )

AXMLは文字列リソースファイルを参照するため、resources / values /strings.xmlを開いて次の変更を加えます。

type TZInfo = { tzName:string localTime: string }

これで、フロントエンドAXMLが構築されました。それでは、それをいくつかのコードに接続しましょう。 MainActivity.fsに移動し、onCreate関数に次の変更を加えます。

button.Click.Add (fun args -> let webClient = new WebClient() let tzi = JsonConvert.DeserializeObject(webClient.DownloadString('https://fivepm.azurewebsites.net/')) txtView.Text <- sprintf 'It's (about) 5PM in the %s Timezone! Specifically, it is %s there' tzi.tzName tzi.localTime )

fivepm.azurewebsites.netを独自のJSONAPIデプロイメントのURLに置き換えます。アプリケーションを実行し、エミュレーターのボタンをクリックします。少しすると、JSONAPIがAPI結果とともに返されるのがわかります。

JSONの解析

もうすぐ着きます!現在、アプリは生のJSONを表示しており、かなり判読できません。次のステップは、JSONを解析し、より人間が読める文字列を出力することです。 JSONを解析するには、サーバーからNewtonsoft.JSONライブラリを使用できます。

NuGetパッケージマネージャーに移動し、Newtonsoft.JSONを検索します。インストールして、MainActivity.fsファイルに戻ります。 「openNewtonsoft.Json」を追加してインポートします。

次に、TZInfoタイプをプロジェクトに追加します。サーバーからTZInfoを再利用することもできますが、実際には2つのフィールドしか必要ないため、ここでカスタムタイプを定義できます。

|_+_|

main関数の上に型定義を追加し、次のようにmain関数を変更します。

|_+_|

これで、JSON APIの結果がTZInfoオブジェクトに逆シリアル化され、文字列の作成に使用されます。アプリを実行し、ボタンをクリックします。フォーマットされた文字列が画面に表示されます。

このアプリケーションは非常にシンプルで、おそらく洗練されていませんが、F#JSON APIを使用してデータを変換し、ユーザーに表示するモバイルアプリケーションを構築しました。そして、すべてF#で行いました。さまざまなコントロールを自由に試して、デザインを改善できるかどうかを確認してください。

そして、私たちはそれを持っています!シンプルなF#モバイルアプリケーションとF#JSON APIで、5時の位置をユーザーに通知します。

まとめ

今日は、F#のみを使用して単純なWeb APIと単純なAndroidアプリケーションを構築する方法を説明し、F#言語の表現力とF#エコシステムの強さの両方を示しました。ただし、F#開発の表面をかじっただけなので、今日説明した内容に基づいて、さらにいくつかの投稿を作成します。さらに、この投稿が、独自のF#アプリケーションを構築するきっかけになったと思います。

このチュートリアルで使用したコードは、 GitHub 。また、Webフロントエンドといくつかの追加のベルとホイッスルを備えたバージョンを作成しました。 https://fivepm.azurewebsites.net 。

基本を理解する

F#は関数型言語ですか?

はい。ただし、F#は関数型プログラミング言語だけではありません。これは、命令型、オブジェクト指向、および関数型プログラミングメソッドを含むマルチパラダイム言語です。

F#は何に使用されますか?

F#は、OCamlのバリアントを.NETで実行できるように設計されています。 F#は汎用言語と見なす必要がありますが、その主な目標は、関数型プログラミングを.NETランドスケープに導入することでした。

F#を選択する理由

F#を検討して選択する必要がある理由はいくつかあります。 .NETエコシステムの他の部分との優れた統合を提供します。構文が簡潔なため非常に簡潔であり、豊富な開発ツールに頼ることができます。

いいねの予測:単純なレコメンデーションエンジンのアルゴリズムの内部

バックエンド

いいねの予測:単純なレコメンデーションエンジンのアルゴリズムの内部
WebRTCアプリケーションを構築する1年:スタートアップエンジニアリングの教訓

WebRTCアプリケーションを構築する1年:スタートアップエンジニアリングの教訓

Webフロントエンド

人気の投稿
GitHubWebhookを使用してWebアプリケーションを自動的にデプロイする
GitHubWebhookを使用してWebアプリケーションを自動的にデプロイする
デザイントーク:UXリサーチャーのCaitriaO'Neillとの実際の研究
デザイントーク:UXリサーチャーのCaitriaO'Neillとの実際の研究
プロスポーツフランチャイズ評価
プロスポーツフランチャイズ評価
不完全なハーモニー:SoundCloudとSpotifyの概要
不完全なハーモニー:SoundCloudとSpotifyの概要
データベース設計の悪い習慣:あなたはこれらの間違いを犯していますか?
データベース設計の悪い習慣:あなたはこれらの間違いを犯していますか?
 
ソフトウェアエンジニアのパフォーマンスレビューの説明
ソフトウェアエンジニアのパフォーマンスレビューの説明
Laravelを使用したGraphQLサーバーの構築
Laravelを使用したGraphQLサーバーの構築
シャザム!音楽アルゴリズム、指紋、および処理の認識
シャザム!音楽アルゴリズム、指紋、および処理の認識
WebVRとブラウザエッジコンピューティング革命
WebVRとブラウザエッジコンピューティング革命
デザイナーのための効果的なコミュニケーション戦略
デザイナーのための効果的なコミュニケーション戦略
人気の投稿
  • プライベートエクイティファンドを開始する
  • Twitterからデータを取得する方法
  • レスポンシブデザインのためのメディアクエリの使用方法
  • ステップバイステップの初心者のためのangularjsチュートリアル
  • プットオプションの価格設定方法
カテゴリー
ツールとチュートリアル リモートの台頭 人とチーム 収益性と効率性 Webフロントエンド ヒントとツール モバイル その他 製品ライフサイクル バックエンド

© 2021 | 全著作権所有

apeescape2.com