2017-12-31 46 views
7

fmapもファンクタカテゴリの関数適用($)ですので、<$>です。

(+5) $ (*10) $ 10  -- 105 
(+5) <$> (*10) <$> [1,2,3] -- [15,25,35] 

は、その後、私は<*>はApplicativeのファンクタカテゴリの機能アプリケーションであり、これは動作するはずもその場合には、思った:だから

[(+5), (+10)] <*> [(*10), (*100)] <*> [1,2,3] -- ERROR 
-- however: 
[(+5), (+10)] <*> ([(*10), (*100)] <*> [1,2,3]) -- [15,25,35,...] 

、機能のためのfmapがあることを起こるので<$>だけうまくいきますしたがって、(+5) <$> (*10)(+5) . (*10)になり、[1,2,3]に適用されます。

しかし、すべてのアプリケーションオペレータ(<<=が含まれています)の左の連想は、私には、特に右の連想である$との類似性を認識した後、貧しいデザインの選択肢のようです。これには別の理由がありますか?

+2

機能アプリケーションは、本質的である左連想。より良い質問はなぜ '$'が正しい連想であるかということでしょうか? – chepner

+1

また、 'fmap'は、functionアプリケーションではなくfunction * lifting *と考えられます。 'fmap'が持ち上げられた関数を返すと、他の関数と同じように適用されます。特別なアプリケーションは必要ありません。 – chepner

答えて

7

実際、理由はおそらく、<$><*>が1つの優先レベルを共有できるからです。我々は間違いなく<*>が左結合することが

Prelude> foldr <$> [(+),(*)] <*> [0,1] <*> [[1,2,3], [4,5,6]] 
[6,15,7,16,0,0,6,120] 

作品のようなので、ものたい、これも<$>は、それが高い優先順位を持っていないにもかかわらず、正しい方法を振る舞うことができます。実際に複数の<$>演算子を連鎖することは、実際には左連想ではあまり役に立ちません。

ただし、右結合性ではあまり役に立ちません。。 chepnerがコメントしたように、実際にはちょっと面白く、$は右結合である。確かに、それは

Prelude> sum $ map (+3) $ take 19 $ cycle [4..7] 
160 

のような組成物を書くことができますが、その後、ここで計算チェーンが解析されているので、これは単なるだけでなく、おそらくよりエレガント

Prelude> sum . map (+3) . take 19 . cycle $ [4..7] 
160 

(よりエレガントな私が言う、のように書くことができ命令型ではなく単一の機能パイプラインとして“これを実行してから、それを実行してください。”)。ファンクタの法則のおかげで、これは<$>.と全く同じ方法で、$.のようにすることができます。

マルチプル$のスタイルを好む唯一の理由は、パイプライン内のインフィックスの表現を可能にする点です。最も一般的な例は、レンズの更新です(通常はフリップされた&で書かれていますが、 ):$&は、かなりはるかに低い任意の中置演算子よりも非常に低い優先度を持っているので

Prelude Control.Lens> [4..7] & ix 1+~9 & ix 2*~8 
[4,14,48,7] 

これは動作します。それはあなたがそのような場合には

Prelude Control.Lens> ix 1+~9 <$> [[4..8], [5..9]] 

<interactive>:23:1: error: 
    Precedence parsing error 
     cannot mix ‘+~’ [infixr 4] and ‘<$>’ [infixl 4] in the same infix expression 

を行うことはできません<$>の場合ではないのです、あなた必要はとにかく、いくつかの括弧を使用するには、その後、あなたは同様に、低優先順位の合成作用素でそれを行う可能性がありますControl.Categoryから:

Prelude Control.Lens Control.Category> (ix 1+~9 >>> ix 2*~8) <$> [[4..8], [5..9]] 
[[4,14,48,7,8],[5,15,56,8,9]] 

または各アップデータの周りの括弧付き:

Prelude Control.Lens> (ix 1+~9) . (ix 2*~8) <$> [[4..8], [5..9]] 
[[4,14,48,7,8],[5,15,56,8,9]] 
関連する問題