すべてのRubyをHaskellであるかのように書いても大丈夫でしょうか?


10

Rubyには、リスト作成、マップ、選択、収集などの優れたリスト操作機能が組み込まれています。Procs、Blocks、Lambdasがあり、優れた反復サポート(eachファミリ)があるので、もしもRubyのものをすべて最も純粋に機能的な方法で記述しますか?I / Oがほとんどまたはまったくない(したがって、明らかな副作用が少ない)コードに特に適していますか?

私はHaskell(「本当の」ハッカーの言語と呼ばれます)を学んでいて、それを行う方法に夢中になっています。 Rubyはそもそも借りたり、そこから多くを学んだりしませんか?)

建設的なガイダンスは大歓迎です...


13
では、なぜHaskellで書いてみませんか?

1
私はHaskellだけで書こうと思いますが、Rubyは完全に捨てられるに値するほど悪くはありません。スクリプトを作成するときに使用できることと、多くの簡単な実験のために、AIのことを学ぶときに一緒にハッキングすることが好きです。しかし、おそらく私がHaskellの学習を始めたばかりであるため、最終的にはアドバイスに従うかもしれません:-)
nemesisfixx

2
Stack Overflowの許可を求めている理由がわかりません。チームの他の人と共有するコードを書いている場合、とにかくコーディングスタイルを調整する必要があります。そうでなければ、それは何が問題ですか?
Mike Daniels、

なぜSOを求めているのですか?経験豊富なハッカーやプログラマーの正直な意見を尊重するからです。純粋な関数型アプローチをプログラミングに使用すると、経験豊富な心が私(および私のような他の人)と共有できる利点があるかもしれません。
nemesisfixx 2011

「いいえ」の客観的な理由があることを考えると、これは正当な質問です。
Andrew Grimm、

回答:


16

私はこれをpythonで行っています。そのために設計されていない言語で、伝統的に純粋な関数型のスタイルで書くのは面倒です。たとえば、in_orderの2つの定義を対比します。

def in_order(xs):
    for i in range(1,len(xs)):
        if xs[i] > xs[i+1]:
            return False
    return True

inOrder :: (Ord a) => [a] -> Bool
inOrder xs = and $ zipWith (<=) xs (tail xs)

書き込みin_orderpythonでHaskellの方法は、(のpythonは非常によく、必要なイディオムをサポートしていないので)両方の冗長可能と低速(線形空間の代わりに、怠惰のためにHaskellの一定の空間)になるだろう。

しかし、私は機能的な編成と各関数の慣用的な実装を備えたpythonプログラムの作成に成功しました。これがプログラミングの良い方法であるという考えは、実際には私のcodecatalogプロジェクトの背後にある論文です。したがって、私のコンポーネントは、状態を持つクラスではなく、抽象化とそれらに作用する(純粋なインターフェースを持つ)関数を中心にしており、うまく統合されています。実際、この方法で編成されたコードは、クラスで編成されたコードよりも柔軟に再利用できます。しかし、私はまだハスケルの信者なので、それは個人的な偏見かもしれません。

だから私はあなたの質問への答えはちょっとだと思います。機能的なルーツを使用して考えやすくしますが、無理しないでください。例えば。イディオムのためだけにRubyで遅延リストをシミュレートすることは、おそらくそれよりも厄介なことになるでしょう。


どういうわけかあなたの説明は私にパスカルを思い起こさせました。
rasjani 2011

@rasjani、おお?なぜですか?

よくわかりません。英語をよく理解していない、またはパスカル単位で配置/構造化された場所にどのように(少なくとも)何を記述したのかがわかります。一種の精神的なつながりであり、最初のオプションが原因で実際​​のつながりがないかもしれません;)
rasjani

1
「怠惰によるHaskellの定数空間ではなく線形空間」という記述は正確ではありません。怠惰は依然として線形秩序を意味します。しかし、私はあなたの要点を理解しています。

3
@aromero、あなたのことは分かりませんが。注文はそれとどのような関係がありますか?一定のスペースは、Haskellのガベージが比較のリストの先頭をand消費した後にそれらを収集することから生じます。ループのように動作します。一方、Pythonの比較のリストは、の類似体andがそれらのいずれかを表示する前に完全に生成する必要があります(ジェネレーターを使用しない限り...これは可能性があると思います)。

7

Rubyコードは、HaskellではなくSchemeのように機能的なスタイルで記述できます。それをHaskellであるかのように書くには、Haskellに似た型システムと、広範にわたる遅延評価が必要になります。


1

Rubyで遭遇した特定の状況で、関数型プログラミング、特にHaskellを理解することが役立つことがわかりました。しかし、Haskellを学べば学ぶほど、RubyがHaskellのようになることができることから、どれほど遠くにあるかがわかります。

モジュール/コードの読み込み状況はひどいです。現在のインタープリターでは末尾呼び出しの最適化がオンになっていないため、Haskellで行うように再帰を使用することはできません。そして、Monadsに入ると、HaskellとRubyで実現できる抽象化のレベルを比較することはできません。

興味があれば、Ruby / Haskellの比較コードをgist.github.comに投稿してきました。

私がRubyにもたらした手法の中で最も優れたものは、できる限り純粋な関数を見つけることでした。つまり、あなたがしようとしているように思えます。


私のSmalltalkの試験の一つで:self assert: ((m >>= f) >>= g) equals: (m >>= [:x | (f value: x) >>= g])。(リストのように)モナドを使用していることに気付かずにモナドを使用するのとは対照的に、モナドを意識的に使用できない理由はまったくありません。
フランクShearar

0

「はい」と言います。あなたが話している(私が思う)のは、ルビ言語における関数型プログラミングの影響です。機能的パラダイムには、オブジェクト指向を補完または重複する(特に副作用がない)いくつかの非常に優れた概念があります。

Rubyの優れた点は、線形、オブジェクト指向、または機能的なスタイル、またはこれらのブレンドでコーディングできることです。そして、複雑さが増すと、シンプルな線形スクリプトがOO / Functionalスタイルに変形する可能性があります。


0

他の人とコラボレーションするかどうかによります。自分でコードに取り組んでいる場合は、最も使いやすいスタイルを使用してください。ただし、他のRubyプログラマーと作業している場合、それらは純粋に関数型のプログラミングに慣れていない可能性があり、そのため、コードによって混乱する可能性があります。また、共同作業者がRubyに移行したHaskellプログラマでもある場合は、この問題は発生しない可能性があります。

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