まあ、弱いタイピングと強いタイピングはかなり曖昧に定義されています。さらに、「強い型付け」の一般的な使用法に最も近いのは、型をキャストするのを困難にするものを参照することであるため、さらに強力な型システムを説明することはできません。30ポンド未満しか持てない場合は弱く、もっと持ち上げることができる人は誰でも同じカテゴリーの「強い」という誤解を招く区別になります。
だから私は定義を好む:
- 弱く型付けされたシステムは型を使用して、特定のこと(ミスなど)を防ぐことができます
- 強く型付けされたシステムは型を使用してあなたのために物事を行います
あなたのために何かをするということはどういう意味ですか?さて、Servantフレームワークでの画像変換APIの作成を調べてみましょう(Haskellでは、実際にそれを知る必要はありません。
{-# LANGUAGE
TypeOperators,
DataKinds
#-}
import Codec.Picture
import Data.Proxy
import Network.Wai.Handler.Warp (run)
import Servant
import Servant.JuicyPixels
main :: IO ()
main = run 8001 conversion
これは、ServantパッケージやServantへのJuicyPixelsプラグインを含むいくつかのモジュールが必要であり、プログラムの主なエントリポイントは、Warpバックエンドを使用するサーバーとしてポート8001で「変換」機能を実行することです。言語ビットを無視します。
conversion :: Application
conversion = serve (Proxy :: Proxy ConversionApi) handler
これは、変換関数はAPIが「ConversionApi」タイプと一致する必要があるサーバーであり、要求は関数によって処理されることを意味しています handler
type ConversionApi
= ReqBody '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage
:> Post '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage
これはConvesionApi
タイプを指定しています。リスト '[BMP、GIF、JPEG 50、PNG、TIFF、RADIANCE]で指定された着信コンテンツタイプを受け入れ、それらをDynamicImageとして処理し、同じ範囲のコンテンツに変換されたDynamicImageを返す必要があると述べています。タイプ。:>の意味を正確に心配する必要はありません。今のところ、それを幸せな魔法と考えてください。
したがって、私の好みの定義を考えると、弱く型付けされたシステムは次のようなことを保証できます:
- 間違った発信コンテンツタイプを返さない
- 着信リクエストを間違ったコンテンツタイプとして解析しない
- サーバーがより複雑な場合、不正な形式のURIを作成できなくなりますが、リンクを含むHTMLページを実際に返すわけではありません(そして、このタイプはできないことを保証します!)
- 非常に野心的な弱いタイピングシステムは、すべての着信および発信コンテンツタイプを徹底的に処理していることを確認し、タイプが単なる制約ではなく仕様文書としても機能することを確認することさえあります。
上記の定義を考慮すると、すべての高尚な目標ですが、実際には厳密に型指定されたシステムとしての資格を得るには十分ではありません。そして今、私たちは実際にこの仕様に従うコードを書くことの難しい部分に到達しなければなりません。非常に強力な型システムでは、次のように記述します。
handler = return
そして、これで完了です。それだけです、書くコードはもうありません。これは完全に機能するWebサーバーです(私が見逃したタイプミスを修正します)。型は、定義してインポートした型とパッケージ(技術的にはモジュール)からWebサーバーを作成するために必要なすべてをコンパイラーに伝えました。
それでは、主要なアプリケーション規模でこれを行う方法をどのように学びますか?まあ、それは小規模なアプリケーションでそれらを使用することと実際にはそれほど違いはありません。絶対型は、それらに関連するコードの量を気にしません。
実行時の型検査はおそらく避けるべきものです。なぜなら、型によって物事を単純化するのではなく、それによって莫大な利益が失われ、型を使ってプロジェクトをより複雑にすることができるからです。
そのため、ほとんどの場合、型を使用したモデリングの練習問題にすぎません。モノのモデリング(または一般的なビルド)の2つの主な方法は、ボトムアップとトップダウンです。トップダウンは、最高レベルの操作から始まり、モデルを構築するにつれて、後までモデリングを延期する部分があります。ボトムアップモデリングとは、基本機能で開始するのと同様に、基本操作で開始し、プロジェクトの操作を完全にキャプチャするまで、ますます大きなモデルを構築することを意味します。ボトムアップはより具体的であり、おそらくビルドがより高速ですが、トップダウンは、実際にどのように動作する必要があるかについて、下位レベルのモデルによりよく知らせることができます。
タイプは、プログラムが文字通り数学とどのように関係するかであるため、複雑さの上限や、それについて学習を「完了」できるポイントは実際にはありません。事実上、高レベルの大学コース以外のすべてのリソースは、特定の言語でのタイプの動作に専念しているため、同様に決定する必要があります。
私が提供できる限り、型は次のように階層化できます。
- [] + {}が定義されているJavaScriptなどの非常に弱い型付け
- [] + {}ができないPythonのように弱く型付けされていますが、試してみるまでチェックされません
- [] + {}ができないCやJavaのような弱い型付けですが、コンパイル時にチェックされますが、より高度な型機能はありません
- C ++テンプレートメタプログラミングなど、弱く強く型付けされた型と、型がプロパティを強制するだけの単純なHaskellコードとの境界をまたぐ。
- 上に示したように、型が処理するより複雑なHaskellプログラムのように、完全に型付けされた完全に
- AgdaやIdrisのように、型と値が相互作用し、互いに制約することができる非常に強く型付けされたもの。これは、型システムが得るのと同じくらい強力であり、それらでのプログラミングは、プログラムが何をするかについて数学的な証明を書くのと同じです。注:Agdaでのコーディングは、文字通り数学的証明を書いているのではなく、型は数学的理論であり、それらの型を持つ関数はそれらの理論を証明する建設的な例です。
一般的に、このリストの下方に行くほど、タイプができることは多くなりますが、最下部までには成層圏に登っており、空気が少し薄くなっています-パッケージのエコシステムははるかに小さく、あなたは関連するライブラリを見つけた場合と比べて、より多くのものを自分で記述する必要があります。また、大規模なプログラムを書くのに十分な型システムを実際に理解する必要があるため、エントリの障壁も低くなります。