“适用”是什么意思?

时间:2012-01-10 03:34:03

标签: haskell

在阅读Haskell上的内容时,我有时会遇到形容词" applicative",但我无法找到这个形容词的足够清晰的定义(而不是比方说,哈斯克尔的Applicative班。我想学习识别一段代码/算法/数据结构等,即#34; applicative",就像我能识别出一个"递归"。一些对比的例子" applicative"与任何术语打算区别开来的(我希望它本身比#34;非适用的"更有意义的东西)将非常感激。

编辑:例如,为什么单词" applicative"选择命名这个类,而不是其他名字?是什么让这个名称Applicative非常适合它的类(即使以其默默无闻的代价)?

谢谢!

2 个答案:

答案 0 :(得分:21)

在不了解背景的情况下,不清楚“应用”是什么意思。

如果它真的没有引用applicative functor(即Applicative),那么它可能指的是应用程序本身的形式:f a b c是一个 applicative 形式,这个应用仿函数的名字来源于:f <$> a <*> b <*> c是类似的。 (的确,idiom brackets通过让你把它写成(| f a b c |)来进一步加强这种联系。)

类似地,“应用语言”可以与主要不基于对参数的函数应用(通常以前缀形式)的语言形成对比;例如,连接(“基于堆栈”)语言不适用。

为了回答为什么应用仿函数被称为深度的问题,我建议阅读 Applicative programming with effects;基本思想是很多情况都需要“强化应用程序”之类的东西:在一些有效的上下文中应用纯函数。比较mapmapM的这些定义:

map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs

mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]
mapM _ [] = return []
mapM f (x:xs) = do
  x' <- f x
  xs' <- mapM f xs
  return (x' : xs')

mapA(通常称为traverse):

mapA :: (Applicative f) => (a -> f b) -> [a] -> f [b]
mapA _ [] = pure []
mapA f (x:xs) = (:) <$> f x <*> mapA f xs

正如您所看到的,mapA更简洁,更明显与map相关(如果您在(:)中使用map的前缀形式,则更是如此太)。实际上,即使你有一个完整的Monad,使用应用函子表示法在Haskell中也很常见,因为它通常要清楚得多。

查看定义也有帮助:

class (Functor f) => Applicative f where
  pure :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b

(<*>)的类型与应用类型进行比较:($) :: (a -> b) -> a -> bApplicative提供的是一种通用的“提升”应用程序形式,使用它的代码是以 applicative 样式编写的。

更正式地说,正如文章中提到并由ertes指出的那样,ApplicativeSK combinators的概括; pureK :: a -> (r -> a)(又名const)的概括,而(<*>)S :: (r -> a -> b) -> (r -> a) -> (r -> b)的概括。 r -> a部分简单地推广到f a;使用Applicative的{​​{1}}实例获取原始类型。

实际上,((->) r)还允许您以更统一的方式编写应用表达式:pure而不是pure f <*> effectful <*> pure x <*> effectful

答案 1 :(得分:15)

在更基础的层面上,可以说“适用”意味着以某种形式的SK微积分工作。这也是Applicative类的内容。它为你提供了组合子pure(K的推广)和<*>(S的推广)。

当您的代码以这种风格表达时,它是适用的。例如代码

liftA2 (+) sin cos

的适用表达
\x -> sin x + cos x

当然在Haskell中,Applicative类是应用程序样式编程的主要构造,但即使在monadic或arrowic上下文中,您也可以编写应用程序:

return (+) `ap` sin `ap` cos

arr (uncurry (+)) . (sin &&& cos)

最后一段代码是否具有应用性是有争议的,因为有人可能会认为应用风格需要合理化。