Clojure が関数型パラダイムを強調しているにもかかわらず、なぜMaybe
/Option
モナドを使用してオプションの値を表現しないのでしょうか? の使用はOption
、私が定期的に使用する関数型プログラミング言語である Scala で非常に普及しています。
7 に答える
Clojure は静的に型付けされていないため、haskell (および、Scala) で必要な厳密な this/that/whatever 型宣言は必要ありません。文字列を返したい場合は、文字列を返します。代わりに nil を返しても問題ありません。
「機能」は「厳密なコンパイル時の型付け」に正確には対応しません。これらは直交する概念であり、Clojure は動的型付けを選択します。map
実際、かなり長い間、静的型付けを保持しながら、高階関数のような多くの関数を実装する方法を想像できませんでした。Haskell の経験が少し (ほとんど) ないので、それが可能であり、実際には非常にエレガントであることがわかります。Clojure をしばらく使ってみると、逆の経験をすることになると思います。型宣言は、関数型言語で慣れ親しんだような力を与えるのに必要ではないことに気付くでしょう。
Clojure では、nil punning は、Scala と Haskell が Option と Maybe から取得する機能のほとんどを提供します。
**Scala** **Clojure**
Some(1) map (2+_) (if-let [a 1] (+ 2 a))
Some(1) match { (if-let [a 1]
case Some(x) => 2+x (+ 2 a)
case None => 4 4)
}
Scala の Option と Haskell の Maybe はどちらも Applicative のインスタンスです。これは、内包表記でこれらの型の値を使用できることを意味します。たとえば、Scala は以下をサポートします。
for { a <- Some(1)
b <- Some(2)
} yield a + b
Clojure の for マクロは、seq に対する理解を提供します。モナド内包表記とは異なり、この実装ではインスタンス タイプを混在させることができます。
Clojure の for は、複数の可能な nil 値に対する関数を構成するために使用することはできませんが、実装するのは簡単な機能です。
(defn appun [f & ms]
(when (every? some? ms)
(apply f ms)))
そしてそれを呼び出す:
(appun + 1 2 3) #_=> 6
(appun + 1 2 nil) #_=> nil
Maybe/Option は型です。関数型プログラミングとは何の関係もありません。はい、一部の言語 (Scala、haskell、ocaml) は機能的であるだけでなく、非常に強力な型システムも提供します。Haskell については、WITH TYPES プログラミングだとさえ言われます。
他のもの (clojure、lisp) は、完全に機能する関数型言語であるにもかかわらず、型に関してあまり提供しません。それらの重点は異なり、Maybe/Option タイプは適合しません。単純に、動的言語ではあまり役に立ちません。たとえば、シーケンス (リスト、ベクター、マップ) を操作する多くの clojure 関数は、null (nil) を完全に受け入れ、空の構造として扱います。
(count nil) は 0 を返します。(count []) と同じです。
Clojure は「型を使ったプログラミング」とは言えません。
Maybe モナドはありますが、nil を Nothing として使用し、計算の抽象化のみをキャプチャします (input=nil の場合は nil を返し、それ以外の場合は入力で何でも計算します)。null ポインター エラーを回避しますが、静的なコンパイル時の安全性はありません。同様の使命を持つfnilもあり、 nil にデフォルト値と-?>をパッチします。clojure の方法は、エラーまたは nil を発生させるデフォルト値を返すことに重点を置いていると思います。
@amalloyを使用して、Clojureは言語として、オプションの戻り値は必要ないとコメントしています。
私はScalaをあまり使っていませんが、Clojureは、値を処理できるようにするために、returntypeに関する厳密な詳細を知る必要はありません。これは、Maybeモナドが埋め込まれ、通常のClojure評価の一部になったかのようです。操作の多くは、で実行された場合nil
、に戻りnil
ます。
Clojure-Contribライブラリをざっと見てみましたが、モナドパッケージがあります。Clojureのモナドをどのように利用するかについて私を本当に手がかりにしたもう1つの項目は、Clojureのモナドに関するCosminのチュートリアルです。これが、Scalaでより明示的に記述されている機能が動的Clojure言語の一部としてどのように処理されるかを結び付けるのに役立ちました。