2013-11-14 6 views
7

Clojureには「スレッディングマクロ」->->>があります。私はそれがよさそうだかどうかを確認するために働いスルーの例を見てみたいClojureのスレッディングマクロに相当するScalaは何ですか?

var myObj = MyObject(x, y, z) 
myObj = transform(myObj, abc) 
myObj = transformMore(myObj, def) 
myObj = transformYetMore(myObj, bar) 

:私は、同様の構造のようなコードを置き換えるためにScalaのコードで使用することができますかなり確信しています。私はあなたがScalaの場合にマクロを使う必要はないと確信しています。

+0

あなたがそれぞれ作曲andThenのようなものを意味ですか? –

+0

F#pipeまだ私のお気に入り:) – Alex

答えて

2

私はこのような何かが便利になることができるいくつかの例を考えることができます。一例を与えるために、私はデータセットで働いていると、このように前方に結果を運んでいる間、私はそれにいくつかの機能を適用したい:

val result: ResultSet = Functions.thread(inputSet) 
           .andThen(execute(_, executionContext)) 
           .andThen(_.filter(_.nonEmpty)) 
           .andThen(verifyData(_, verificationHelper)) 
           .andThen(_.cache) 
           .andThen(saveSnapshot) 

スレッドせずに同じことを作成するには、いずれかの巣の呼び出しにする必要がありますか中間関数呼び出しの結果を保存します。私は、コードの保守性と可読性を向上させるより少ない行数で同じことをするので、上記の方法を使用する方が好きです。ここで

は、これを達成するためのユーティリティですFunctions

object Functions { 
    def thread[T](item: T) = new ThreadFunctor(item) 
} 

class ThreadFunctor[T](val item: T) { 
    def andThen(f: T => T): ThreadFunctor[T] = new ThreadFunctor(f(item)) 
} 

object ThreadFunctor { 
    implicit def threadToItem[T](thread: ThreadFunctor[T]): T = thread.item 
} 
0

clojureのスレッド化マクロは、過度にネストされた式の問題を解決するために使用されるため、一般的なコレクション関数はきれいであるため、スカラではなんらかの種類のスレッドユーティリティを使用することはほとんどありません

def square(x: Int) = x * x 
def plusOne(x: Int) = x + 1 
List(1,2,3,4).map(square).map(plusOne) 

あるいは長いもの:

someCollection.map(...) 
       .flatMap(...) 
       .filter(...) 
       .map(...) 
       ... 

他の選択肢は(はるかに有用なオプションと先物のための)理解のためです。これに満足できない場合は、マクロを使用する必要はありません。そのような構文についてのブログ記事がたくさんあります。例えば、this one

+4

私は実際には、特に機能コードでは珍しいとは思わない;あなたの最初の例は本当に 'List(1,2,3,4).map(square andThen plusOne)'と見なすと思います。あなたが呼び出すモナドの場合、これはさらに真実です。変数を渡すだけの私の理解のためのものではなく、むしろKleisliの構成を見ています。 – Hugh

関連する問題