2016-04-01 9 views
2
traverse :: Applicative f => (a -> f b) -> t a -> f (t b) 

こんにちは、私は署名を理解できない機能がたくさんあります
。もちろん、トラバースには2つの引数があります。最初は関数です。しかし、
何を意味するのですか(a -> f b)?私は(a -> b)を理解することができます。
と同様に、t a,理解署名

私に説明してもらえますか?

+1

'f'は型コンストラクタを表します(' f = Maybe'と考えてください) 't'(' t = [] ')と思っています - '(a - > Maybe b) - >たぶん[b] '? – Carsten

+1

この場合の感情を知りたければ、 '' traverse(\ a - > evenでもあれば '' div' 2)以外の何も再生できません)[2,4,6] ''(入力リストを変更してみてください);) – Carsten

+0

ありがとうございます。私に教えてください:tはいつも[a]を意味しますか? –

答えて

3

traverseはタイプ派生関数なので、この関数の動作は曖昧にはtを選択することによって決まります。これは>>=またはfmapと似ていません。しかし、そのような場合と同じように、行動のルールがあります。このルールはtraversea -> f bという機能を持ち、aからbへの効果的な変換であり、全体の「コンテナ」がaで動作するようにリフトし、それぞれのローカル変換の効果を収集するという考えを捉えています。例えば

、我々はMaybe aを持っている場合traverseの実装はリスト

traverse f [a1, a2, ...] = (:) <$> f a1 <*> ((:) <$> f a2 <*> ...)) 

私たちは「効果」fであるという事実を利用している方法をお知らせするために

traverse f (Just a) = Just <$> f a 
traverse f Nothing = pure Nothing 

だろうファンクタだけでなく、適用可能なので、我々はf af bの2つのf-ful計算をとり、それらを一緒に粉砕してf (a, b)を得ることができる。 すべてトラバースが行うことができることを説明するいくつかの法律を考え出し、要素にfを適用し、外部への影響を収集しながら元のt aを構築します。私たちは、

traverse Identity = Identity -- We don't lose elements 
t . traverse f = traverse (t . f) -- For nicely composing t 
traverse (Compose . fmap g . f) = Compose . fmap (traverse g) . traverse f 

は今、これは非常に複雑に見えますが、それはやっているすべては「基本的に周りの散策や地元の変換を適用する」の意味を明確にあると言います。このすべてはあなただけtraverseが何をするか理解するために署名を読むことはできませんが、署名のためのOK直感が

  • 我々はa秒のf :: a -> f b
  • ファンクタフルローカル、副作用の機能を得るということであるに沸きますffmap
  • すべてのエフェクトがそのように蓄積されたala我々はだけではなく、私たちはf (t b)を取得し、戻って繰り返しfを適用することで得bの完全なファンクタを取得
  • 10。

ただし、traverseは奇妙な方法で使用することができます。たとえば、レンズパッケージには、非常に奇妙なファンクタを使ってtraverseを使用することができます。

簡単なテストとして、法律traverseを使用してtfmapを実装する方法を理解できますか?つまり、これらの両方がトラバースインスタンスもFunctorFoldableを満たしているという事実の結果である

fmapOverkill :: Traversable f => (a -> b) -> (f a -> f b) 

それともheadMay

headMay :: Traversable t => t a -> Maybe a 

です!