30

我刚刚Const在 的文档中找到了Control.Applicative,但我很难弄清楚这在哪里有用,而不是直接使用Monoid

我错过了什么?

4

4 回答 4

28

Traversable.

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

这是将一堆东西粘在一起的一般方法。这是让我相信值得ApplicativeMonad. 我需要通用的东西elem

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

Traversable Term对由自由变量表示的参数进行发生检查。我一直在改变 的表示,Term我厌倦了修改无数的遍历函数,其中一些是在做累积,而不是有效的映射。我很高兴找到一个涵盖两者的抽象。

于 2012-07-17T23:32:28.553 回答
7

当您拥有适用于所有 ( Applicative)Functor的函数或数据结构并希望在退化的意义上重用它时,它很有用。它类似于传入const或传递id给给定任意函数的函数。

Van Laarhoven 透镜是根据任意 Functor 定义的,并用于Const派生字段访问器(以及派生字段更新器同样微不足道Identity)。

Traversable正如 pigworker 所提到的,类型是另一个例子。

于 2012-07-18T10:33:15.697 回答
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
于 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 回答