简体   繁体   English

(<*>):: f(a-> b)-> fa-> fb在Functor类中到底做了什么

[英]what does (<*>) :: f (a -> b) -> f a -> f b exactly do in the Functor class

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

From my understanding, it takes a function f, where another function (a -> b) as its argument, returns a function f . 据我了解,它采用一个函数f,其中另一个函数(a -> b)作为其参数返回一个函数f Applying f to a then returns a function f and apply f to b . f应用于a然后返回函数f并将f应用于b

Here is an example: 这是一个例子:

Prelude> (+) <$> Just 2 <*> Just 3
Just 5

But I don't quite understand how it works. 但是我不太了解它是如何工作的。

I guess (+) should be f , Just 2 and Just 3 should be a and b respectively. 我猜(+)应该是fJust 2Just 3应该分别是ab Then what is (a -> b) ? 那么(a -> b)什么?

From my understanding, it takes a function f... 据我了解,它需要一个函数来...

Unfortunately this is incorrect. 不幸的是,这是不正确的。 In this case, f is a type, not a function. 在这种情况下, f是类型,而不是函数。 Specifically, f is a "higher-kinded type" with kind * -> * . 具体地说, f是类型为* -> *的“高级类型”。 The type f is the functor. 类型f是函子。

In this case, f is Maybe . 在这种情况下, fMaybe So we can rewrite the function types, specializing them for Maybe : 因此,我们可以重写函数类型,使其专门用于Maybe

pure :: a -> Maybe a
(<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b

It starts to become a bit clearer once you get this far. 到此为止,它将变得更加清晰。 There are a couple different possible definitions for pure , but only one that makes sense: 对于pure ,有两种不同的可能定义,但是只有一种才有意义:

pure = Just

The operator x <$> y is the same as pure x <*> y , so if you write out: 运算符x <$> ypure x <*> y ,因此如果您写出:

(+) <$> Just 2 <*> Just 3

Then we can rewrite it as: 然后我们可以将其重写为:

pure (+) <*> pure 2 <*> pure 3

Although this technically has a more general type. 尽管从技术上讲,这是更通用的类型。 Working with the functor laws, we know that pure x <*> pure y is the same as pure (xy) , so we get 使用函子定律,我们知道pure x <*> pure ypure (xy)相同,因此我们得到

pure ((+) 2) <*> pure 3
pure ((+) 2 3)
pure (2 + 3)

In this case, we a and b are the types but since <*> appears twice they actually have different types in each case. 在这种情况下,我们ab类型,但是由于<*>出现两次,因此它们实际上在每种情况下都有不同的类型。

In the first <*> , a is Int and b is Int -> Int . 在第一个<*>aIntbInt -> Int In the second <*> , both a and b are Int . 在第二个<*>ab均为Int (Technically you get generic versions of Int but that's not really important to the question.) (从技术上讲,您获得的是Int通用版本,但这对问题并不是很重要。)

Applicative functors were introduced to Haskell as applicative style programming "Idioms" . 应用函子作为应用样式编程“成语”引入Haskell。 Unpacking this phrase, we have "applicative style programming"; 解开这个短语,我们有“应用样式编程”; which is just application of functions to arguments. 这只是函数对参数的应用。 We also have "idioms", or phrases in a language which have a special meaning. 我们也有“成语”或具有特殊含义的语言短语。 For example "raining cats and dogs" is an idiom for raining very heavily. 例如,“给猫和狗下雨”是下大雨的习语。 Putting them together, applicative functors are function applications with special meaning. 应用函子放在一起,是具有特殊含义的函数应用程序。

Take for example, following Dietrich Epp's lead, anApplication defined by a function, 例如,在Dietrich Epp的带领下,一个函数定义了一个anApplication

anApplication = f a
  where
    f = (+2)
    a = 3

and, anIdiomaticApplication , defined with idiomatic application, anIdiomaticApplication ,通过惯用应用程序定义,

anIdiomaticApplication = f <*> a
   where 
     f = Just (+2)
     a = Just 3

The top level structure of these definitions are similar. 这些定义的顶层结构相似。 The difference? 区别? The first has a space--normal function application--and the second has <*> --idiomatic function application. 第一个具有空格-正常功能应用程序-第二个具有<*>惯用功能应用程序。 This illustrates how <*> facilitates applicative style: just use <*> in place of a space. 这说明<*>如何促进应用风格:只需使用<*>代替空格。

The application, <*> , is idiomatic because it carries a meaning other than just pure function application. 应用程序<*>是惯用的,因为它具有除纯函数应用程序以外的含义。 By way of exposition, in anIdiomaticApplication we have something like this: 通过说明的方式,在一个anIdiomaticApplication我们有这样的东西:

 f <*> a :: Maybe (Int -> Int) <*> Maybe Int

Here, the <*> in the type is used to represent a type level function* that corresponds to the signature of the real <*> . 在此,类型中的<*>用于表示与真实<*>签名相对应的类型级别函数*。 To the type- <*> we apply the type arguments for f and a (respectively Maybe (Int -> Int) and Maybe Int ). 对于类型<*>我们将fa (分别为Maybe (Int -> Int)Maybe Int )应用类型参数。 After application we have 申请后,我们有

 f <*> a :: Maybe Int

As an intermediate step, we can imagine something like 作为中间步骤,我们可以想像

 f <*> a :: Maybe ((Int -> Int) _ Int)

With _ being the type level stand-in for regular function application. _是常规功能应用程序的类型级别替身。

At this point we can finally see the idiom-ness called out. 在这一点上,我们终于可以看到习惯用语了。 f <*> a is like a normal function application, (Int -> Int) _ Int , in the Maybe context/idiom. Maybe上下文/习惯用法中, f <*> a类似于常规函数应用程序(Int -> Int) _ Int So, <*> is just function application that happens within a certain context. 因此, <*>只是在特定上下文中发生的函数应用程序。

In parting, I'll emphasize that understanding <*> is only partially understanding its use. 在分开时,我将强调理解<*>仅部分理解其用法。 We can understand that f <*> a is just function application which some extra idiomatic meaning. 我们可以理解, f <*> a只是函数应用程序,具有一些特殊的含义。 Due to the Applicative laws, we can also assume that idiomatic application will be somehow sensible. 根据适用法律,我们还可以假定惯用的应用会在某种程度上是明智的。

Don't be surprised, however, if you look at <*> and get confused since there is so little there. 但是,如果您查看<*>并感到困惑,因为那里的内容很少,请不要感到惊讶。 We must also be versed in the various Haskell Idioms. 我们还必须精通各种Haskell习语。 For instance, in the Maybe idiom either the function or value may not be present, in which case the output will be Nothing . 例如,在Maybe惯用语中,函数或值都可能不存在,在这种情况下,输出将为Nothing There are of course, many others, but getting familiar with just Either a and State s should model a wide variety of the different kinds. 当然,还有很多其他人,但是只要熟悉Either aState s ,就应该为各种不同的模型建模。

*Something like this could actually be made with a closed type family (untested) *像这样的事情实际上可以由封闭型家庭(未经测试)完成

type family IdmApp f a where
   IdmApp (f (a->b)) a = f b

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Functor用于(a - &gt; b) - &gt;(fa - &gt; fb),什么是(类别c)=&gt; cab - &gt; c(fa)(fb)? - Functor is for (a -> b) -> (f a -> f b), what is for (Category c) => c a b -> c (f a) (f b)? Haskell:是否有这样的运算符:(&lt;$$&gt;):: Functor f =&gt; fa-&gt;(a-&gt; b)-&gt; fb - Haskell: Is there an operator like this: (<$$>) :: Functor f => f a -> (a -> b) -> f b ((fa)b)与Haskell中的(fab)相同吗? - Is ((f a) b) the same as (f a b) in Haskell? &#39;f&#39;在仿函数的fmap函数中表示什么? - What does the 'f' represent in the fmap function of a functor? Haskell 中的“f (a -&gt; b)”类型签名是什么意思? - What does “f (a -> b)” type signature mean in Haskell? bi fab的通用变体=(fa,fb) - Generic variant of bi f a b = (f a, f b) 为什么类型f(fbc)(f(fab)(fac))不匹配(。)? - Why doesn't the type f (f b c) (f (f a b) (f a c)) match (.)? 如果f是a-&gt; b类型的函数,则(fmap f)与(f。)相同吗? - Is (fmap f) the same as (f .) if f is a function of type a->b? 为什么在 Applicative 上 pure 的类型是 a -> fa,而不是 (a -> b) -> f (a -> b)? - Why type of pure is a -> f a, not (a -> b) -> f (a -> b) on Applicative? f, g, h :: Kleisli ((-&gt;) e) ab &lt;=&gt; f &gt;&gt;&gt; (g &amp;&amp;&amp; h) = (f &gt;&gt;&gt; g) &amp;&amp;&amp; (f &gt;&gt;&gt; h)? - f, g, h :: Kleisli ((->) e) a b <=> f >>> (g &&& h) = (f >>> g) &&& (f >>> h)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM