質問

私は、離散構造の下位区分コースを教えます。テキストブック離散構造、ロジック、計算可能性を選択しました。関数型プログラミング言語での実装に役立つ例と概念が含まれています。 (また、良い教科書だと思います。)

DSの概念を説明し、学生が使用できるわかりやすいFP言語が必要です。ほとんどの学生は、せいぜい1学期または2学期のJavaプログラミングしか受けていません。 Scheme、Erlang、Haskell、Ocaml、およびSMLを調べた後、HaskellまたはStandard MLのいずれかに決めました。以下に概説する理由からHaskellに傾倒していますが、どちらか一方でアクティブなプログラマーである人々の意見が欲しいです。

  • HaskellとSMLの両方には、再帰アルゴリズムの記述を簡単にするパターンマッチングがあります。
  • Haskellには、そのようなリストが数学的に表現される方法とうまく一致する素晴らしいリスト内包表記があります。
  • Haskellの評価は遅延しています。リスト内包法を使用して無限リストを作成するのに最適です。
  • SMLには、関数を定義および使用できる真のインタラクティブインタープリターがあります。 Haskellでは、関数は別のファイルで定義し、インタラクティブシェルで使用する前にコンパイルする必要があります。
  • SMLは、関数の引数を明確に確認し、理解しやすい構文で型を返します。例:val foo = fn:int * int-> int。 Haskellの暗黙的なカレー構文はもう少し鈍いですが、完全に異質ではありません。例:foo :: 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ではできません!

役に立ちましたか?

解決

Haskellが大好きなのと同じように、離散数学とデータ構造のクラス(および他のほとんどの初心者クラス)にSMLを好む理由は次のとおりです。

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

  • インタラクティブインタープリターの関数定義の構文は、ファイルで使用される構文と同一なので、カットアンドペーストできます。

  • SMLの演算子のオーバーロードは完全に偽ですが、それも簡単です。型クラスに入らずにHaskellでクラス全体を教えるのは難しいでしょう。

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

  • 無限のデータ構造は人々の心を吹き飛ばします。初心者には、参照セルとサンクで完全なストリームタイプを定義してもらい、その仕組みを理解してもらうとよいでしょう:

    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 は混乱を招きます。

関連トピックについては、コースの準備に関するいくつかのアドバイスがあります。を見落とさないでください。クリス・オカサキによる純粋に機能的なデータ構造。生徒にそれを使わせなくても、必ずコピーを手に入れたいでしょう。

他のヒント

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

学生がよく気づいた問題:

  • パターンマッチングは、最初は少し難しい場合があります。学生は当初、値の構築とパターンマッチングがどのように関連しているかを理解するのにいくつかの問題がありました。また、抽象化を区別する際にいくつかの問題がありました。私たちの演習には算術式を簡素化する関数の記述が含まれ、一部の学生は抽象的な表現(たとえば、 Const 1 )とメタ言語表現( 1 )の違いを見るのが困難でした。 。

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

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

    どの程度の機能プログラミングを途中で教えたいかに応じて、それらにいくつかのライブラリ関数を与えて、それらを試してみることができます。

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

  • 彼らはリストの内包表記をすぐに発見し、 filter map zipWith のような高次関数よりも優先しました。

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

  • 通常、エラーメッセージは初心者にはあまり役に立たないため、これらのヘルプが必要になる場合があります。私は自分で試したことはありませんが、主に優れたエラーメッセージを使用して、特に初心者向けのHaskellコンパイラがあります:ヘリウム

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

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

ところで、

  

#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を使用すれば、楽しみのためにマルチコア並列処理を教えることができます:-)

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

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

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

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

ハグにはその制限がありますが、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->
  •   

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から始める初心者にはお勧めできません。しかし、単純なアルゴリズムを試すだけで、本格的なアプリケーションを構築するつもりはありません。

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

  • nominoloの考えを改めて、リストの内包表記は do して、生徒がいくつかの高階関数に到達するのを遅らせているようです。
  • 遅延と無限のリストが必要な場合は、明示的に実装することをお勧めします。
  • SMLは熱心に評価されているため、実行モデルの理解がはるかに容易であり、「printfを介したデバッグ」 Haskellよりもずっと良く機能します。
  • SMLの型システムも簡単です。あなたのクラスはおそらくそれらを使用しないでしょうが、Haskellの型クラスはまだ乗り越えるための余分なバンプです。 SMLは十分に厳しいです。

ほとんどの答えは技術的でしたが、少なくとも1つは考慮しないべきだと思います。Haskell(OCamlとして)は、現時点では、より広いコンテキストでより大きなコミュニティを使用しています。 ハッカーには、利益のために書かれたライブラリとアプリケーションの大きなデータベースもあります。これは、コース終了後に一部の学生が言語を使用し続けるのに重要な要素になる可能性があります。また、後で他の機能言語(標準MLなど)を試すこともできます。

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

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

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

ただし、SMLの学習ははるかに簡単です。 Haskellには、遅延評価や制御構造などの機能があり、はるかに強力になりますが、学習曲線が急勾配になります。 SMLにはそのような曲線はありません。

とはいえ、Haskellの大部分は、Ruby、ObjC、Pythonなどの科学的/数学的でない言語からの学習を行っていませんでした。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top