79

私は個別の構造で下位部門のコースを教えるつもりです。私がテキスト ブックDiscrete Structures, Logic, and Computabilityを選択した理由の 1 つは、関数型プログラミング言語での実装に役立つ例と概念が含まれているためです。(私も良い教科書だと思います。)

DS の概念を説明し、学生が使用できる、わかりやすい FP 言語が必要です。ほとんどの学生は、せいぜい 1 学期か 2 学期の Java プログラミングしか経験していません。Scheme、Erlang、Haskell、Ocaml、SML を検討した結果、Haskell または標準 ML のいずれかに落ち着きました。以下に概説する理由から、私は Haskell に傾倒していますが、いずれかのアクティブなプログラマーの意見を求めています。

  • Haskell と SML の両方にパターン マッチングがあり、再帰アルゴリズムの記述が簡単になります。
  • Haskell には、そのようなリストを数学的に表現する方法とうまく一致する優れたリスト内包表記があります。
  • Haskell には遅延評価があります。リスト内包表記法を使用して無限リストを構築するのに最適です。
  • SML には、関数の定義と使用の両方が可能な真にインタラクティブなインタープリターがあります。Haskell では、関数は別のファイルで定義し、対話型シェルで使用する前にコンパイルする必要があります。
  • SML は、理解しやすい構文で関数の引数と戻り値の型を明示的に確認します。例: val foo = fn : int * int -> int. Haskell の暗黙のカリー構文はもう少し鈍いですが、完全に異質というわけではありません。例: foo :: Int -> Int -> Int。
  • Haskell はデフォルトで任意精度の整数を使用します。SML/NJ の外部ライブラリです。また、SML/NJ はデフォルトで出力を 70 文字に切り捨てます。
  • Haskell のラムダ構文は巧妙で、単一のバックスラッシュを使用します。SML はより明示的です。ただし、このクラスでラムダが必要になるかどうかはわかりません。

基本的に、SML と Haskell はほぼ同等です。Haskell のリスト内包表記と無限リストが大好きなので、Haskell に傾倒しています。しかし、Haskell のコンパクトな構文の膨大な数のシンボルが学生に問題を引き起こすのではないかと心配しています。SOに関する他の投稿を読んで集めたものから、HaskellはFPから始める初心者にはお勧めできません。ただし、本格的なアプリケーションを構築するつもりはなく、単純なアルゴリズムを試すだけです。

どう思いますか?


編集:あなたの素晴らしい回答のいくつかを読んで、私の箇条書きのいくつかを明確にする必要があります.

SML では、インタープリターでの関数の定義と外部ファイルでの関数の定義の間に構文上の違いはありません。階乗関数を書きたいとしましょう。Haskell では、この定義をファイルに入れ、GHCi にロードできます。

fac 0 = 1
fac n = n * fac (n-1)

私にとって、それは明確で簡潔であり、本の数学的定義と一致しています。しかし、GHCi で関数を直接書きたい場合は、別の構文を使用する必要があります。

let fac 0 = 1; fac n = n * fac (n-1)

対話型インタープリターを使用する場合、教育の観点からは、学生がファイルとコマンド ラインの両方で同じコードを使用できると非常に便利です。

「関数の明示的な確認」とは、関数を定義すると、SML がすぐに関数の名前、引数の型、および戻り値の型を通知することを意味します。Haskell では、:typeコマンドを使用する必要があり、やや混乱するカレー表記が表示されます。

Haskell のもう 1 つの優れた点 - これは有効な関数定義です。

fac 0 = 1
fac (n+1) = (n+1) * fac n

繰り返しますが、これは彼らが教科書で見つけるかもしれない定義と一致します。SML ではできません。

4

8 に答える 8

90

私は Haskell が大好きですが、個別の数学とデータ構造のクラス (および他のほとんどの初心者向けクラス) に SML を好む理由は次のとおりです。

  • Haskell プログラムの時間とスペースのコストは、専門家であっても予測が非常に難しい場合があります。SML は、マシンを吹き飛ばすためのはるかに限定された方法を提供します。

  • 対話型インタープリターでの関数定義の構文は、ファイルで使用される構文と同じであるため、カット アンド ペーストできます。

  • SML での演算子のオーバーロードは完全に偽物ですが、単純でもあります。型クラスを使わずに Haskell でクラス全体を教えるのは難しいでしょう。

  • 生徒は を使用してデバッグできprintます。(ただし、コメンターが指摘しているように、Haskell で を使用してほぼ同じ効果を得ることができDebug.Trace.traceます。)

  • 無限のデータ構造は人々の心を吹き飛ばします。初心者の場合は、ref セルとサンクを備えた完全なストリーム タイプを定義してもらい、それがどのように機能するかを理解してもらうことをお勧めします。

    datatype 'a thunk_contents = UNEVALUATED of unit -> 'a
                               | VALUE of 'a
    type 'a thunk = 'a thunk_contents ref
    val delay : (unit -> 'a) -> 'a thunk
    val force : 'a thunk -> 'a
    

    これはもはや魔法ではなく、ここからストリーム (無限リスト) に移動できます。

  • レイアウトは Python ほど単純ではなく、混乱する可能性があります。

Haskell が優れている点は 2 つあります。

  • コア Haskell では、関数の型シグネチャをその定義の直前に書くことができます。これは、学生やその他の初心者にとって非常に役立ちます。SML で型シグネチャを処理する良い方法はありません。

  • Haskell の方が具体的な構文が優れています。Haskell 構文は、ML 構文よりも大幅に改善されています。ML プログラムでいつ括弧を使用するかについて、短いメモを書きました。これは少し役立ちます。

最後に、両方向を切断する剣があります。

  • Haskell コードはデフォルトで純粋であるため、生徒が誤って不純な構造 (IO モナド、状態モナド) に出くわすことはほとんどありません。しかし、同じように、それらは印刷できず、I/O を実行したい場合は、少なくともdo表記法を説明する必要があり、return混乱します。

関連トピックとして、コースの準備に関するアドバイスがあります。Chris Okasaki によるPurely Functional Data Structuresを見逃さないでください。生徒に使わせなくても、絶対に1冊は持っておきたくなるはずです。

于 2009-05-01T22:59:49.780 に答える
29

大学では、Haskell を 1 年生に教えています。これについての私の気持ちは少し複雑です。一方では、Haskell を 1 年生に教えることは、命令型のスタイルを忘れる必要がないことを意味します。Haskell は非常に簡潔なコードを生成することもできます。これは、以前に Java を使用したことがある人にとってありがたいものです。

私が気づいたいくつかの問題は、学生がよく持っているものです:

  • パターン マッチングは、最初は少し難しいかもしれません。生徒たちは最初、値の構築とパターン マッチングがどのように関連しているかを理解するのに苦労しました。また、抽象化を区別する際にも問題がありました。Const 1私たちの演習には、算術式を単純化する関数の記述が含まれており、一部の生徒は抽象的な表現 (例: ) とメタ言語表現 ( )の違いを理解するのが困難でした1

    さらに、学生がリスト処理関数を自分で作成することになっている場合は、パターンの違いを指摘するように注意してください。

    []
    [x]
    (x:xs)
    [x:xs]
    

    途中でどれだけ関数型プログラミングを教えたいかにもよりますが、いくつかのライブラリ関数を渡して、それをいじってもらうこともできます。

  • 私たちは生徒たちに無名関数については教えませんでしたwhere。節について説明しただけです。一部のタスクでは、これは少し冗長でしたが、それ以外の場合はうまく機能しました。また、部分的なアプリケーションについても説明しませんでした。これは、おそらく Haskell で説明するのが非常に簡単であるため (型の記述形式のため)、彼らに見せる価値があるかもしれません。

  • 彼らはすぐにリスト内包表記を発見しfilter、 、mapzipWith.

  • タイプによって思考を誘導する方法を彼らに教えるのを少し逃したと思います。ただし、これが初心者にとって役立つかどうかはよくわかりません。

  • 通常、エラー メッセージは初心者にはあまり役に立ちません。私は自分で試したことはありませんが、特に初心者向けの Haskell コンパイラがあり、主にエラー メッセージが改善されています: Helium

  • 小さなプログラムの場合、スペース リークの可能性などの問題はありませんでした。

全体として、Haskell は優れた教育用言語ですが、いくつかの落とし穴があります。学生が高階関数よりもリスト内包表記に慣れていることを考えると、これはあなたが必要とする議論かもしれません。コースの長さやプログラミングの量はわかりませんが、基本的な概念を教える時間を計画してください。必要になるでしょう。

于 2009-05-01T13:11:49.443 に答える
14

ところで、

# SML には、関数を定義して使用できる、真にインタラクティブなインタープリターがあります。Haskell では、関数は別のファイルで定義し、対話型シェルで使用する前にコンパイルする必要があります。

不正確です。GHCi を使用します。

Prelude> let f x = x ^ 2
Prelude> f 7
49
Prelude> f 2
4

haskell.org edu には、教育における Haskell の優れたリソースもあります。さまざまな教師の経験を含むページ。http://haskell.org/haskellwiki/Haskell_in_education

最後に、Haskell を使用すれば、楽しみのためにマルチコア並列処理を教えることができます :-)

于 2009-05-01T14:54:52.113 に答える
13

多くの大学では Haskell を最初の関数型言語または最初のプログラミング言語として教えているので、これは問題にはならないと思います。

そのようなコースでいくつかの教えを行ったので、あなたが特定した可能性のある混乱がそれほどありそうなものであることに同意しません. 初期の混乱の原因として最も可能性が高いのは、不適切なレイアウトによる解析エラーと、数値リテラルが正しく使用されていない場合の型クラスに関する謎のメッセージです。

また、Haskell は FP を使い始める初心者にはお勧めできないという提案にも同意しません。これは確かに、突然変異を伴う厳密な言語にはないビッグバン アプローチですが、非常に有効なアプローチだと思います。

于 2009-05-01T07:14:38.803 に答える
9
  • SML には、関数の定義と使用の両方が可能な真にインタラクティブなインタープリターがあります。Haskell では、関数は別のファイルで定義し、対話型シェルで使用する前にコンパイルする必要があります。

Hus にはその制限があるかもしれませんが、GHCi には次のような制限はありません。

$ ghci
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> let hello name = "Hello, " ++ name
Prelude> hello "Barry"
"Hello, Barry"

私が Hugs よりも GHC(i) を好む理由はたくさんありますが、これはその 1 つにすぎません。

  • SML は、理解しやすい構文で関数の引数と戻り値の型を明示的に確認します。例: val foo = fn : int * int -> int. Haskell の暗黙のカリー構文はもう少し鈍いですが、完全に異質というわけではありません。例: foo :: Int -> Int -> Int。

SML には、いわゆる「暗黙のカリー」構文もあります。

$ sml
Standard ML of New Jersey v110.69 [built: Fri Mar 13 16:02:47 2009]
- fun add x y = x + y;
val add = fn : int -> int -> int

基本的に、SML と Haskell はほぼ同等です。Haskell のリスト内包表記と無限リストが大好きなので、Haskell に傾倒しています。しかし、Haskell のコンパクトな構文の膨大な数のシンボルが学生に問題を引き起こすのではないかと心配しています。SOに関する他の投稿を読んで集めたものから、HaskellはFPから始める初心者にはお勧めできません。ただし、本格的なアプリケーションを構築するつもりはなく、単純なアルゴリズムを試すだけです。

私は SML よりも Haskell を使う方がずっと好きですが、それでも SML を最初に教えます。

  • nominolo の考えに倣うと、リスト内包表記学生が高階関数にたどり着くのを遅らせるように見えます。
  • 遅延と無限リストが必要な場合は、明示的に実装することをお勧めします。
  • SML は積極的に評価されるため、実行モデルははるかに理解しやすく、"printf によるデバッグ" は Haskell よりもはるかにうまく機能します。
  • SML の型システムも単純です。とにかくあなたのクラスはそれらを使用しない可能性が高いですが、Haskell の型クラスはまだ乗り越えなければならない余分な問題です.SML の'a''aの違いを理解させることは十分に困難です.
于 2009-05-01T15:08:48.273 に答える
5

OCamlとF#があなたの懸念の多くに対処していることを考えると、それらを考慮していないことに驚いています。確かにまともで役立つ開発環境は、学習者にとって最優先事項ですか?その点で、SMLははるかに遅れており、F#は他のすべてのFPLよりもはるかに進んでいます。

また、OCamlとF#の両方にリスト内包表記があります。

于 2009-05-12T19:44:26.273 に答える
5

ハスケル。Haskell を使用して学んだことのおかげで、CS のアルゴリズム/理論のクラスで先を行っています。それは非常に包括的な言語であり、それを使用するだけで大​​量の CS を学習できます。

ただし、SML の学習ははるかに簡単です。Haskell には、遅延評価や制御構造などの機能があり、Haskell をはるかに強力にしますが、学習曲線が急な (っぽい) という代償を伴います。SML にはそのような曲線はありません。

とはいえ、Haskell のほとんどは、Ruby、ObjC、Python などの科学的/数学的ではない言語からの学習を放棄していました。

于 2015-03-11T21:10:39.757 に答える