2015-11-08 20 views
9

私はScalaから来ました。ハスケルの左から右への連鎖方法(右から左へと反対)

putStrLn . show . map (**2) . filter (< 3) $ [1..10] 

を、この:私は$.を使用して、すべてのネストされた括弧を取り除くことができます発見した後、私は最近、自分が書いた、

Haskellで
println((1 to 10).filter(_ < 3).map(x => x*x)) 

:だから私はしばしばのようなものを行いますコードは右から左に読み込まれますが、アラビア語に移行しない限り、これは私が推論するのが難しいです。

私は左から右に機能をチェーン化する他のトリックはありますか?それとも、これはちょうどハスケルの慣用的な方法ですか?

+1

と表記することができます。「putStrLn。 show = print'。また、 'mapM'や' forM'を使うこともできます: 'forM [x | x < - [1..10]、x <3] $ print。 (** 2) 'のようなものです。 – Bakuriu

+0

これに慣れれば、左から右へ推論するのが簡単になります。それはあなたに式のタイプを与えます。あなたのケースでは 'putStrnLn ...'私はIOだと分かっています。 – mb14

+1

役に立たない観察:通常の連鎖関数アプリケーション(関数合成を使用しない)の 'flow'は右から左です: 'f。 g。 h $ x = f(g(h)(x))) 'となる。これは非常に古い規則です(Cのような構文でも保持されるため、ハスケル主義だけではありません)。これは、関数合成演算子ではなく、「後方」であるドットメソッド構文です。 Scalaの例では、 'flow'はトレースするのがずっと難しいことに注意してください。実際には '(1〜10)'の中間で始まり、次に右に移動してから、突然左に戻って 'println'にジャンプします。 – Ben

答えて

16

残念ながら、それはハスケルの慣用方法です。しかし、オペレーター&はあなたが望むことをするかもしれません。

import Data.Function ((&)) 

[1..10] & filter (< 3) & map (**2) & show & putStrLn 

実質的に(&) = flip ($)。同様に、Control.Arrow.(>>>) = flip (.)

UPDATE(6+ヶ月後):私は認めざるを得ないは、この問題は私にとってフラストレーションの大きな源であり、私はこの潜在的な解決策をいじるされています:

https://gist.github.com/obadz/9f322df8ba6c8a9767683d2f86af8589#file-directionalops-hs-L81

+2

'x&f >>> g'は間違った優先順位のために失敗します。それは' g。 f $ x'となる。 – chi

2

なぜ新しい演算子を作成しませんか?

(#) :: a -> (a -> b) -> b 
(#) = flip id 

今、あなたはちょうどこれがData.Functionから(&)演算子と同等です

[1..10] # filter (< 3) # map (**2) # show # putStrLn 

を書くことができます。

5

はい、それはハスケルの慣用句です。アラビア語ではなく、むしろMathematicで、構文の構文から派生したものです。 Haskell composition (.) vs F#'s pipe forward operator (|>)も参照してください。

はまだ、でもHaskellで、あなたは時々、他の方向にあなたの呼び出しを記述することを好む、あなたはいくつかのライブラリを見つけることができます(例えばData.Function以来の基本4.8.0)

(&) = flip ($) 

ように定義されています電話を

[1..10] & filter (< 3) & map (**2) & show & putStrLn 
+0

私が個人的に左から右の連鎖演算子を逃した唯一の時間は、[モナドの 'fmap']でした(http://stackoverflow.com/q/20203056/1048572)。 – Bergi

関連する問題