繁体   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

据我了解,它采用一个函数f,其中另一个函数(a -> b)作为其参数返回一个函数f f应用于a然后返回函数f并将f应用于b

这是一个例子:

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

但是我不太了解它是如何工作的。

我猜(+)应该是fJust 2Just 3应该分别是ab 那么(a -> b)什么?

据我了解,它需要一个函数来...

不幸的是,这是不正确的。 在这种情况下, f是类型,而不是函数。 具体地说, f是类型为* -> *的“高级类型”。 类型f是函子。

在这种情况下, fMaybe 因此,我们可以重写函数类型,使其专门用于Maybe

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

到此为止,它将变得更加清晰。 对于pure ,有两种不同的可能定义,但是只有一种才有意义:

pure = Just

运算符x <$> ypure x <*> y ,因此如果您写出:

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

然后我们可以将其重写为:

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

尽管从技术上讲,这是更通用的类型。 使用函子定律,我们知道pure x <*> pure ypure (xy)相同,因此我们得到

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

在这种情况下,我们ab类型,但是由于<*>出现两次,因此它们实际上在每种情况下都有不同的类型。

在第一个<*>aIntbInt -> Int 在第二个<*>ab均为Int (从技术上讲,您获得的是Int通用版本,但这对问题并不是很重要。)

应用函子作为应用样式编程“成语”引入Haskell。 解开这个短语,我们有“应用样式编程”; 这只是函数对参数的应用。 我们也有“成语”或具有特殊含义的语言短语。 例如,“给猫和狗下雨”是下大雨的习语。 应用函子放在一起,是具有特殊含义的函数应用程序。

例如,在Dietrich Epp的带领下,一个函数定义了一个anApplication

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

anIdiomaticApplication ,通过惯用应用程序定义,

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

这些定义的顶层结构相似。 区别? 第一个具有空格-正常功能应用程序-第二个具有<*>惯用功能应用程序。 这说明<*>如何促进应用风格:只需使用<*>代替空格。

应用程序<*>是惯用的,因为它具有除纯函数应用程序以外的含义。 通过说明的方式,在一个anIdiomaticApplication我们有这样的东西:

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

在此,类型中的<*>用于表示与真实<*>签名相对应的类型级别函数*。 对于类型<*>我们将fa (分别为Maybe (Int -> Int)Maybe Int )应用类型参数。 申请后,我们有

 f <*> a :: Maybe Int

作为中间步骤,我们可以想像

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

_是常规功能应用程序的类型级别替身。

在这一点上,我们终于可以看到习惯用语了。 Maybe上下文/习惯用法中, f <*> a类似于常规函数应用程序(Int -> Int) _ Int 因此, <*>只是在特定上下文中发生的函数应用程序。

在分开时,我将强调理解<*>仅部分理解其用法。 我们可以理解, f <*> a只是函数应用程序,具有一些特殊的含义。 根据适用法律,我们还可以假定惯用的应用会在某种程度上是明智的。

但是,如果您查看<*>并感到困惑,因为那里的内容很少,请不要感到惊讶。 我们还必须精通各种Haskell习语。 例如,在Maybe惯用语中,函数或值都可能不存在,在这种情况下,输出将为Nothing 当然,还有很多其他人,但是只要熟悉Either aState s ,就应该为各种不同的模型建模。

*像这样的事情实际上可以由封闭型家庭(未经测试)完成

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

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM