在阅读Haskell上的内容时,我有时会遇到形容词"applicative",但我无法找到这个形容词的足够清晰的定义(与Haskell的Applicative类相反).我想学习识别一段代码/算法/数据结构等"应用",就像我能识别出一个"递归"的那样.一些对比的例子"应用"与任何术语打算区别(我希望它本身比"非应用"更有意义的东西)将非常感激.
编辑:例如,为什么选择"applicative"这个词来命名这个类,而不是其他名字?这个课程的名称是什么让它Applicative非常适合它(即使是以其默默无闻的代价)?
谢谢!
ehi*_*ird 21
在不了解背景的情况下,不清楚"应用"是什么意思.
如果它真的不是指应用仿函数(即Applicative),那么它可能指的是应用程序本身的形式:f a b c是一个应用形式,这就是应用仿函数得名的地方:f <$> a <*> b <*> c类似.(事实上,成语括号通过让你把它写成来进一步发展这种联系(| f a b c |).)
类似地,"应用语言"可以与主要不基于对参数的函数应用(通常以前缀形式)的语言形成对比; 例如,连接("基于堆栈")语言不适用.
为了回答为什么应用仿函数被称为深入的问题,我建议阅读
带有效果的应用编程 ; 基本思想是很多情况都需要"强化应用程序"之类的东西:在一些有效的上下文中应用纯函数.比较这些map和的定义mapM:
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')
Run Code Online (Sandbox Code Playgroud)
与mapA(通常称为traverse):
mapA :: (Applicative f) => (a -> f b) -> [a] -> f [b]
mapA _ [] = pure []
mapA f (x:xs) = (:) <$> f x <*> mapA f xs
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,mapA是更简洁,更明显相关map(更是这样,如果你使用的前缀形式(:)中map太).实际上,即使你有一个完整的,使用应用函子符号Monad在Haskell中很常见,因为它通常要清楚得多.
查看定义也有帮助:
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
比较(<*>)应用类型的类型:($) :: (a -> b) -> a -> b.什么Applicative提供是一个广义的"解禁"申请的形式,并使用代码它是写在一个应用性的风格.
正如文章中提到的并且由ertes指出的更正式Applicative的是SK组合器的概括; pure是K :: a -> (r -> a)(又名const)(<*>)的概括,是一种概括S :: (r -> a -> b) -> (r -> a) -> (r -> b).该r -> a部分简单地概括为f a; 原始类型是通过Applicative实例获得的((->) r).
作为一个实际问题,pure还允许您以更统一的方式编写应用表达式:pure f <*> effectful <*> pure x <*> effectful而不是(\a b -> f a x b) <$> effectful <*> effectful.
小智 15
在更基础的层面上,可以说"适用"意味着以某种形式的SK微积分工作.这也是Applicative课程的内容.它给出了组合子pure(K的推广)和<*>(S的推广).
当您的代码以这种风格表达时,您的代码是适用的.例如代码
liftA2 (+) sin cos
Run Code Online (Sandbox Code Playgroud)
是一个适用的表达
\x -> sin x + cos x
Run Code Online (Sandbox Code Playgroud)
当然在Haskell中,Applicative类是应用程序样式编程的主要构造,但即使在monadic或arrowic上下文中,您也可以编写应用程序:
return (+) `ap` sin `ap` cos
arr (uncurry (+)) . (sin &&& cos)
Run Code Online (Sandbox Code Playgroud)
最后一段代码是否具有应用性是有争议的,因为有人可能认为应用风格需要合理化才有意义.