Haskellの型システムは、関数型プログラミングを理解する上での障害ですか?[閉まっている]


33

私は関数型プログラミングを理解する目的でHaskellを勉強していますが、他の言語(Groovy、Python、JavaScriptを中心に)で得た洞察を適用することを期待しています。

Haskellを選んだのは、非常に純粋に機能的であり、状態への依存を許さないという印象を持っていたからです。

私は非常に厳格な型システムをナビゲートすることに興味があったので、Haskellを学ぶことを選択しませんでした。

私の質問はこれです:強い型システムは非常に純粋な関数型言語の必要な副産物ですか、またはこれはHaskellに特有の無関係な設計選択ですか?


6
明示的に何も入力したくない場合は、明示的に何も入力する必要はありません。Haskellは独自に型を推測できます。そして、2つの互換性のない型を潜在的に格納する単一の変数を持つようになるわけではありません。
アノン。

4
@Anonはい、ただしリストは同種でなければなりません。私を信じてください、この種のことは、型推論でも邪魔になります。
エリックウィルソン

13
@FarmBoyとMaybeの使用の何が問題になっていますか?Javaを使用すると、すべてのクラスでMaybeを実際に使用できますが、これは奇妙なことです。
代替

3
また、異種混合リストを本当に使用したい場合は、もちろん代数データ型を使用できます。
代替

1
この時点で@mathepicは、完全に有効な質問であった私の元の質問の追跡を本当に失いました。
エリックウィルソン

回答:


40

Haskellの型システムを理解することは、関数型プログラミングを理解するためのアンプだと思います。

純粋に関数型のプログラミングに関することは、暗黙的にあらゆる種類のことを行うことができる副作用がない場合、純粋に関数型のプログラミングによってプログラムの構造がより明確になります。

Haskellは、カーペットの下に物を押し込むのを防ぎ、プログラムの構造を明示的に処理するように強制し、これらの構造を記述する言語(型の言語)を教えます。型、特にHaskellのようなリッチな型を理解すると、どの言語でも優れたプログラマーになります。

Haskellが強く型付けされていなければ、モナド、応用ファンクターなどの概念がプログラミングに適用されることはなかったでしょう。


2
これは良い答えです、私の追加は、型システムは最初は異常に見えるかもしれませんが、後でより高度な概念を学習し始めると、その型の順守のためにしかできない特定のことがあることがわかりますシステム(上記のリストにSTMおよびData Parallelを追加)。他の型システムではスターターではないものは、Haskellシステムに自然に適合します。私のアドバイス:しばらくそれを使い続けて、時間の経過とともに沈んでいきましょう(「クラム」言語ではありません)。
アノン

2
これは非常に古い答えであることは知っていますが、実際には同意しません。私はスイープ、いくつかのものとして明示的として、特にこのような状態とParsecのようモナドで、言語、型システムであってもよい、ということだと思いTONカーペットの下のもののを。これは実際に、言語のライブラリを学習する私の能力を非常に大きく妨げています。
サバンニD'Gerinel

4
@ SavanniD'Gerinel:この回答では、「カーペットの下に物を投げ込む」とは、暗黙的な機能を追加することではなく(Haskellがモナドなどの制御された方法で行い、ボイラープレートの削減に役立ちます)、むしろコードの一部を許可することです予想外のことを行います。たとえば、Haskellの純粋な関数には副作用がありません。期間。他の多くの言語では、関数のドキュメントでこれを約束できますが、コードのどこかに何らかの副作用を押し込むことを妨げる言語はありません。
ジョルジオ14

33

最も動的に型付けされた関数型言語は、おそらくSchemeです。とはいえ、Haskellの型システムはその純度の指標です。それは「純度をどのように測定するのか」という問題です。Haskellの型システムを使用すると、で不純なアクションを簡単に回避できますIO。そのためには、静的型システムが必要です。

しかし、Haskellの型システムは関数型プログラミングとは何の関係もないとしましょう。型システムがこの教育的な努力においてあなたを助けないだろうと主張することは、まだhub慢の高さでしょう。Haskellの型システムは豊富で複雑であり、C ++やOCamlの型システムと比較すると、さらに興味深いものです。

それは障害ですか?いいえ、それは資産だと思います。IOたとえば、Haskellの怠lazに対処する方法を検討してください。


8
+1 Haskellの型システムは、慣れればあなたの友達になります。
ラリーコールマン

「それを行うには、静的型システムが必要です」。本当に?
ジョンハロップ

1
「C ++およびOCamlの型システムと比較すると、すべてが興味深い」OCamlのファーストクラスの高次モジュール、構造的に型付けされた推論オブジェクトシステム、およびポリモーフィックバリアントを学習しましたか?
ジョンハロップ

2
@JonHarropまたはエフェクトシステム、または純度を測定/評価する何らかの方法。うん、だからこそそれらを比較するのは面白い。異なる選択は異なる言語に対応します。
ローガンカパルド

20

Clojureは動的に型付けされており、Haskellとほぼ同じくらい純粋なので、Haskellの型システムは絶対的な要件というよりも設計上の選択であるという正当な議論があります。どちらにも間違いなく長所があるため、Haskellの剛性が本当に気に入らない場合はClojureを検討することをお勧めします(ただし、以下を参照)。

Haskellを初めて使い始めたとき、型システムは煩わしいと思っていましたが、型推論のためだけにそれを許容しました。私はすぐに、コンパイラが私に許可してくれたとしてもうまくいかないことについてコンパイラが文句を言うタイプエラーの多くを発見しました(例えば、concatMapの代わりに誤ってmapを使用しました)。その後、型チェックに合格したプログラムが通常は正しいか、少なくとも修正に近いことを発見しました。関数の型を変更し、コンパイラーに他に変更する必要があるものを教えてリファクタリングする怠laな段階さえありました。最後に、Haskellの型システムが実際に非常に表現力に富んでいることに気づき、型に関するプログラムの設計を開始しました。それがHaskellの聖杯です。


もう1つ注意すべき点は、SchemeとHaskellの両方を使用して、ほぼ同時に関数型プログラミングを学んだことです(前者はクラス用、後者はおもしろいため)。再帰の理解は、Scheme のsやs よりもHaskellのパターンマッチングの方がはるかに簡単であることがわかりました。これはClojureにも引き継がれると思います。ifcond
ティコンジェルビス

@Larry Coleman:型システムに関する自分自身の経験を正確に説明するための+1:最初にC ++、次にOcaml、そして今や自分自身の言語Felix。はい、コンパイラエラーを追跡してリファクタリングします。
イットリル

8

Haskellの型システムは、純粋なコードから効果を分離する能力の鍵です。別の方法で効果を分離できる場合、または効果を完全に削除しない限り、純粋な関数型プログラミングには強力な静的型システムが必要です。

Haskellは、強力で静的な型システムを持つ言語の非常に良い例です。特にコンピューターサイエンスとプログラミング言語の設計に関する幅広い、丸みのある教育が必要な場合、Haskellは、学ぶべき言語の1つとして優れた選択肢になります。

型システムは大きな障害になるべきではありません。プログラムする人は、動的言語を使用している場合でも、Haskellの型システムを使用してエンコードできる型付け規則に従う傾向があります。Haskellは、C ++やJavaなどの言語と比較した場合に冗長性を軽減する型推論も備えています。エラーメッセージが表示された場合、コンパイラはコンパイル時に、動的型を持つ言語が実行時に通知する内容のみを通知します。

動的型システムの反対は、強い型システムではなく、静的型システムです。強い型システムは弱い型システムの反対です。


1
たとえば、Cは静的に型付けされています。型はありますが、型システムを完全に破壊し、基礎となるマシン固有の表現などをいじるのは簡単です。多くの動的型付け言語OTOHは非常に強く型付けされています-暗黙のキャストはほとんどありません。
Steve314

4

それはあなたが愚かな間違いを犯したときにすぐに教えてくれます。これは役に立ちます。私はこの最後の学期にラケット(スキーム)で働いていましたが、解析されていないs-expを渡して、解析されたastをインタープリターの一部の関数に期待し、中規模のテストスイート。静的な型付けがあれば、すぐに気がついたでしょう。

もちろん、論理エラーを型システムで実際にキャッチすることはできませんが、悪用できる方法の数は大幅に減少します。

同様に、型推論では、必要に応じて型システムを無視できます。まだそこにありますが、あなたの側でアクティブな入力を必要としません。関数のタイプを理解することは依然として役立ちますが、正しいコードは問題なく機能します。

Haskellの純度は、その型システムでエンコードされます。IOモナドは、不純なコードが純粋な関数にリークするのを防ぐタイプレベルの構造体です。したがって、純度はタイプシステムによって保証されます。


8
Haskellの型システムを無視できると思われる場合は、Haskellをあまりコーディングしていないと思います。
エリックウィルソン

関数をタイプアウトし、GHCiにロードし、:tを実行するのと同じくらい無視するほど無視しないでください。ただし、場合によっては、一部のfromIntegralまたはその他の関数を振りかける必要があります。
テオ・ベレール

1
Tyrは、型推論を使用しても、Haskell関数の使用とコーディングの90%が相互に噛み合っているため、型システムと不可解な型チェックエラーメッセージを理解する必要があります。「:t」でさえ、魔法の解決策ではなく、プログラムをコンパイルする方法を理解するための最初のステップにすぎません。
アンドレス

まあ、いくつかの部分は乱雑です、私は同意します。プレリュードの数値はクリーンアップされ修正される可能性があると本当に思っています。なぜなら、現状ではひどい混乱だからです。しかし、主要な機能面のほとんどは非常にきれいです。map、filter、foldr / l、およびその他の楽しい機能関数は非常にうまく機能します。
テオベレール

2

「関数型」言語であるということは、(他のものとは別に)関数がその言語の第一級オブジェクトであることを意味します。

「純粋な」言語であるということは、関数が(プロシージャではなく)数学関数であることを意味します。同じ入力が与えられると、常に同じ出力を生成します。

「純粋な関数型言語」とは、上記の両方が当てはまるものです。私は「pure-を認識していないですLY関数型言語」。

強力な型システムは、純粋で実用的な言語を使用するための1つのクリーンな方法です。これらの型は、コンパイラーが最適化を理解するのに役立ちますが、さらに正確性を保証します。(しかし、それが唯一の方法ではありません。clojureは純粋ですが、Haskellほど強力な型システムを持ちません。)

型システムが煩わしい場合は、Schemeなどのより動的な言語を試すか、Haskellの型推論システムを使用することをお勧めします。


0

はい、型システムは素晴らしい資産です。型システムなしでモナドがどのように機能するか、または一部のコンビネータがどのように動作するかを説明することさえ非常に困難です。Haskellのチュートリアルで、REPLで:tを使用して問題の関数のタイプを最初に検討するように求められる数を検討してください。これは、動的に型付けされた言語では使用できません。確かに、型システムの複雑さはすべて残っています。モナドはまだモナドです。しかし、言語は問題の手を洗い、まったく助けを提供しないことに決めました。あなたはあなた自身の仲間です。私は動的に型付けされた言語をノックしていません。私は彼らを心から愛しています。Schemeは卓越したパワーツールです。しかし、動的言語でモナドのようなものについて話すとき、しばしば記法を発明することに気づくでしょう手続きの種類を説明します。機能的なプログラマーは、何らかの形でタイプと戦います。Haskellの型チェッカーは、その方法を学ぶための優れたツールを提供します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.