Haskell(Spock)上のWebアプリケーション「Hello、world!」を作成します。

Pythonで書くことにうんざりしていました。何か変わったものが欲しかったのです。 Haskellを試すことにしました。 言語はわかりませんが、階乗の計算などのコンソールトレーニングプログラムを作成したくありませんでした。 Haskellとその応用に関する実生活でのかなり多くの投稿を研究した後、私は言語の人気の成長の潜在的なポイントの1つがWebアプリケーションを書くことであることに気付きました。 奇妙なことに、Haskellの下にはかなりの数のWebフレームワークがあります。 私の選択はSpockにありました。なぜなら、説明から判断すると、フレームワークの開発は簡単で迅速だからです。 FlaskでWebアプリケーションを作成した経験があるので、このような異なるアプローチを比較して、同様の問題を解決することは興味深いと思いました。 この記事では、基本的なWebアプリケーションをSpockで作成することにより、Haskellを研究する際の試行錯誤の道筋を可能な限り詳しく説明しようとします。 おそらく、これはHaskellを勉強しようとするかどうか、そして実際に役に立つかどうかを疑う人にとって役に立つでしょう。







Haskellとその調理方法について少し



すべての開発者が新しい言語を学習するときに最初に直面するのは、開発環境の選択と設定です。 もちろん、ノートブックに書くこともできますが、制作プロジェクトの開発に少なくともある程度の経験がある場合、この方法は苦痛を伴います。 ちなみに、Haskellはかなり古い共通言語であり、よく知られているほとんどのエディターとideをサポートしています。 私の友人Haskellistはemacsを使用しています。 私は通常のIDEに慣れているため、IntelliJのプラグインをインストールしました。







また、開発にはスタックが必要です。これは現在標準であり、コンパイラ、パッケージ管理システム、ビルドおよびテストシステムを組み合わせています。







すべてがとてもフレンドリーに見え、インストールに問題はありませんでした。 開発には、Mac OSを使用します。他のシステムではテストしていませんが、Linuxではすべてが問題なく起動するのではないかと考えています。







こんにちは世界!



準備する



チュートリアルに進み、指示に従ってすべてのことを試みます。 そこで、彼らは最初にスタックを介して標準プロジェクトを作成することを提案しています: stack new MyLovelyProlect



。 標準プロジェクトは、 app



src



test



3つのサブフォルダーを持つフォルダーapp



。 これはかなり論理的に見えます。1つはメインアプリケーション用、1つは補助機能用、3つ目はテスト用です。 「Hello、world!」と書いているので、 src



フォルダーとtest



フォルダーは必要ありませんが、削除する必要はありません。そうしないと、他のファイル( HelloWorld.cabal



など)を慎重にクリーンアップする必要があります。







実際には、コード



さらにチュートリアルでは、いくつかのコードをMain.hs



にコピーすることを提案しています。 フラスコが提供するものと比較するために、それをもう少し単純化します。







 {-# LANGUAGE OverloadedStrings #-} module Main where import Web.Spock import Web.Spock.Config app :: SpockM () () () () app = get root $ text "Hello World!" main :: IO () main = do cfg <- defaultSpockCfg () PCNoDatabase () let mw = spock cfg app runSpock 8080 mw
      
      





比較のために、フラスコに同じコードを示します。







 from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" app.run()
      
      





行数では、flaskが8対13で勝ちます。しかし、Haskellは静的に型付けされた言語であり、2行が型決定を占めることを考えると、違いは小さいと思います。 少なくとも上記のコードは、言語をさらに学ぶことを恐れませんでした。







組み立てと打ち上げ



次に、 HelloWorld.cabal



に移動し、 executable HelloWorld-exe



build-depends:



セクションに追加しexecutable HelloWorld-exe



build-depends:



Spock >=0.13



。 サイトのチュートリアルでは、さらに2つの依存関係を含めることが提案されていますが、私の目的のためにはまだ必要ありません。 stack build --fast --pedantic



を使用してアプリケーションをビルドしようとすると、次のエラーが表示されます。







 Error: While constructing the build plan, the following exceptions were encountered: In the dependencies for HelloWorld-0.1.0.0: Spock must match >=0.13, but the stack configuration has no specified version (latest matching version is 0.13.0.0) needed since HelloWorld is a build target. Some different approaches to resolving this: * Consider trying 'stack solver', which uses the cabal-install solver to attempt to find some working build configuration. This can be convenient when dealing with many complicated constraint errors, but results may be unpredictable. * Recommended action: try adding the following to your extra-deps in /Users/dkvasov/Documents/Haskell/Spock/HelloWorld/stack.yaml: Spock-0.13.0.0@sha256:8115862eb4fb84a26fb7bcd34f30acf036bd2e7c4eaf813c185c5562d138bba2 Plan construction failed.
      
      





スタックはSpock stack.yaml



バージョンをインストールする必要があるかを認識していないため、 stack.yaml



ファイルに書き込む必要があります。 そこにextra-deps



を追加して、もう一度ビルドしてみます。 いくつかの同様のエラーが引き続きポップアップし、その結果、 stack.yaml



ファイルに以下が表示されます。







 extra-deps: - Spock-0.13.0.0 - Spock-core-0.13.0.0 - reroute-0.5.0.0 - stm-containers-0.2.16 - focus-0.1.5.2
      
      





その後、すべてが集まった。 私のコレクションアーティファクトは、 .stack-work/dist/x86_64-osx/Cabal-2.4.0.1/build









すべてがコマンドstack exec HelloWorld-exe



で始まり、 localhost:8080



私は切望された「Hello、world!」を見ました。 タンバリンと踊る必要はありませんでした。







何が起こっているのかを把握しようとしています。



これまでのところ、関数型プログラミング(FP)とHaskell言語の特定の知識は使用していません。 開発の基本に関する常識と知識を使用しました。 それ以上はできません。 さらに理解するには、AFについていくつかのことを知る必要があります。 AFはOOPの対極ではありません。 Scala言語に精通している人は、これらの概念の両方が簡単に共存できることを知っています。 FPの対抗策は命令型プログラミングです。 計算の機能モデルは機能の構成に依存しますが、命令モデルはシステムの状態の連続的な変化のプロセスに依存します。 Haskellなどの純粋に関数型の言語では、関数は「純粋」である、つまり、戻り値に加えて、可変状態と「副作用」を含まないと想定されます。 これにより、フィーチャコンポジションを簡単に構築できます。 実際、「純度」の要件は、実世界での関数型言語の使用に多くの制限を課しています。 ただし、Haskellには実稼働アプリケーションが存在するため、実世界で何らかの形で純粋な関数を使用できます。 Main.hs



詳しく見てみましょう。







私が理解しているように、アプリapp



は、 モナドであるSpockM



型の変数です。 おそらく、プログラミングの機能的なスタイルとカテゴリ理論に精通していない場合、それが何であり、なぜそれが必要なのかを初めて理解することはないでしょう。 ただし、モナドはHaskell言語のアプリケーションの基礎であるため、少なくとも基本レベルでこれに対処する必要があります。 このテーマについては、Habréを含むさまざまな程度の詳細な記事がかなりあります。 もちろん、私は彼らをここに連れてきません。 これまでのところ、私はモナドがいわゆる副作用を引き起こすことができるような魔法であると考えることを提案します。 アプリケーションには別のモナドIO



ます。 その副作用は、データの入力/出力です。







SpockMは、他の4つのタイプによってパラメーター化されます。 これらは、データベース接続、セッション、状態、および戻り値に対応しています。 空のアプリケーションの場合、これは必要ないため、常にUnitと呼ばれるタイプ()



使用します。 app



内で、アクションにパスをバインドします。 この場合、ベースパス/



を決定し、アクション "Hello, world! get-









次に、デフォルトの構成を作成し、それをcfg



割り当てます。 次に、 spock



関数を使用して、アプリとcfgのミドルウェアを作成し、目的の起動ポートとともにrunSpock



に転送します。







おわりに



ここで説明するすべてが非常にシンプルであり、英語を話し、脳を装備している人は誰でも、最初のスポックチュートリアルを見れば同じことができることは明らかです。 この記事は、Haskell言語にどのように精通したかについての詳細でした。 次は? さらに、ほとんどすべての学習リソースでは、状態を使用してtodoアプリケーションを作成し、データベースに接続することをお勧めします。







参照資料






All Articles