30

Constのドキュメントで見つけたばかりですが、直接Control.Applicative使用するだけでなく、これが役立つ場所を見つけるのに苦労していMonoidます。

私は何が欠けていますか?

4

4 に答える 4

28

と組み合わせるとかなり便利ですTraversable

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

これが、たくさんのものをまとめるための一般的なレシピです。Applicativeから分離する価値があると確信したユースケースの1つでしたMonad。一般化されたようなものが必要でしたelem

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

Traversable Term自由変数の表現によってパラメータ化された の発生チェックを行います。の表現を変更し続けTerm、無数のトラバーサル関数を変更することにうんざりしていました。そのうちのいくつかは、効果的なマッピングではなく、累積を行っていました。両方をカバーする抽象化を見つけてよかったです。

于 2012-07-17T23:32:28.553 に答える
7

Applicativeすべての( )で機能する関数またはデータ構造がFunctorあり、それを縮退した意味で再利用したい場合に便利です。constこれは、任意の関数を渡して、またはid任意の関数で機能する関数を渡すことに似ています。

Van Laarhovenレンズは、任意のファンクターの観点から定義され、フィールドアクセサーを導出するために使用されます(フィールドアップデーターを導出するためConstにも同様に簡単です)。Identity

Traversable豚職人が言及しているように、タイプはこの別の例です。

于 2012-07-18T10:33:15.697 に答える
7

dave4420が言及しているように、VanLaarhovenレンズのアクセサーとアップデーターの実装にはファンクターが含まれ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
于 2012-10-10T15:07:52.963 に答える
2

Gabriel Gonzalez が指摘しているように、Const はレンズに Getter を提供するために使用されます。http://hackage.haskell.org/package/lens-tutorial-1.0.0/docs/Control-Lens-Tutorial.html . そこでは、Const がファンクターであることだけを使用します。

トラバーサルの場合、完全な Applicative 動作が必要であり、それは pigworker が別の回答で説明したものになります。

于 2015-09-08T07:59:49.740 に答える