2012-07-17 56 views

回答

27

當與Traversable結合使用時,它非常有用。

getConst . traverse Const :: (Monoid a, Traversable f) => f a -> a 

這是將一堆東西組合在一起的一般配方。這是使我確信值得從Monad分離Applicative的用例之一。我需要這樣的東西廣義elem

elem :: Eq x => x -> Term x -> Bool 

做的發生,檢查通過自由變量的參數化表示一個Traversable Term。我一直在改變Term的表示方式,我厭倦了修改一個數十億個遍歷函數,其中一些函數正在進行積累,而不是有效的映射。我很高興找到一個涵蓋兩者的抽象。

+0

http://www.soi.city.ac.uk/~ross/papers/Applicative.html第4部分是遍歷技巧的一個很好的參考 – 2012-07-18 18:08:19

+0

'foldMap id'不會產生約束更少的相同結果('可摺疊'而不是'可穿越')? – 2012-08-27 07:01:45

+1

確實,這就是爲什麼'可摺疊'存在。然而,所有'Traversable'都是'Foldable'是非常有用的,上面是'foldMapDefault'的構造。插件:SHE支持'DefaultSuperclassInstances',因此''Traversable'的一切都是默認默認的'Foldable'。 – pigworker 2012-09-06 08:56:21

6

當您的函數或數據結構適用於所有(ApplicativeFunctor s,並且希望以退化的意義重用它時,它非常有用。這類似於將constid傳遞給賦予任意函數的函數。

Van Laarhoven lenses在任意函子來定義,並使用Const導出字段存取器(和同樣瑣碎Identity導出字段更新器)。

TraversableTraversable類型,正如pigworker提到的,是另一個例子。

7

正如dave4420提到的,爲Van Laarhoven鏡頭實現訪問器和更新包括Const仿函數。爲了詳細說明:

{-# LANGUAGE Rank2Types #-} 

import Control.Applicative 
import Control.Monad.Identity 

-- The definition of Van Laarhoven lenses: 
type Lens a b = forall f . Functor f => (b -> f b) -> (a -> f a) 

-- Getter passes the Const functor to the lens: 
get :: Lens a b -> a -> b 
get l = getConst . (l Const) 

-- Updater passes the Identity functor to the lens: 
modify :: Lens a b -> (b -> b) -> (a -> a) 
modify l f = runIdentity . l (Identity . f) 

set :: Lens a b -> b -> (a -> a) 
set l r = modify l (const r) 

-- Example: ------------------------------------------- 

data Person = Person { _name :: String, _age :: Int } 
    deriving Show 

name :: Lens Person String 
name f (Person n a) = fmap (\x -> Person x a) (f n) 

age :: Lens Person Int 
age f (Person n a) = fmap (\x -> Person n x) (f a) 

main :: IO() 
main = do 
    let john = Person "John" 34 
    print $ get age john 
    print $ set name "Pete" john 
相關問題