"适用"是什么意思?

kjo*_*kjo 12 haskell

在阅读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组合器的概括; pureK :: 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)

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

  • +1表示"应用"一词植根于组合逻辑. (4认同)
  • 实际上,*带有效果的应用程序编程*直接注意到:"这个类通常将S和K从一个环境线程化到一般的线程化." (4认同)