简体   繁体   English

Haskell 中的“f (a -> b)”类型签名是什么意思?

[英]What does “f (a -> b)” type signature mean in Haskell?

I'm trying to understand applicatives in Haskell.我试图了解 Haskell 中的应用程序。 Can't figure out what does following type signature mean:无法弄清楚以下类型签名是什么意思:

f (a -> b)

For example:例如:

foo :: Num a => Maybe (a -> a)
foo = Just (+1)

How can I understand the meaning of Maybe (a -> a) ?我如何理解Maybe (a -> a)的含义? Is it a function?是 function 吗? If it is, which types of arguments are allowed?如果是,允许使用哪些类型的 arguments? Also obviously I'm new in functional programming, will be grateful for any resources on this topic.同样显然我是函数式编程的新手,将不胜感激有关此主题的任何资源。

In functional programming, functions are not so different from numbers or any other kind of value.在函数式编程中,函数与数字或任何其他类型的值没有太大区别。 Really the only difference is that the way you use a function is by applying it to an argument.真正唯一的区别是您使用 function 的方式是将其应用于参数。

A value of type Maybe a is either the value Nothing or it is Just x , where x is of type a . Maybe a类型的值要么是Nothing要么是Just x ,其中xa类型。 So if you have a value of type Maybe (a -> a) , like your foo , it is either Nothing , or it is Just f where f is a function a -> a .因此,如果您有一个Maybe (a -> a)类型的值,就像您的foo一样,它要么是Nothing ,要么是Just f ,其中f是 function a -> a In the least fancy way, you would use it like this:以最不花哨的方式,您可以像这样使用它:

case foo of
    Nothing -> "There was no function"
    Just f -> "There was a function, and its value at 0 is " ++ show (f 0)

So if it turns out that foo is not Nothing , then it contains Just a function as its value.因此,如果事实证明foo不是Nothing ,那么它包含Just a function 作为其值。


@Erich is right that especially the literal expression f (a -> b) is likely to be related to applicative functors, but that is not necessarily so. @Erich 是对的,尤其是字面表达式f (a -> b)可能与应用函子有关,但不一定如此。 For example, a favorite type of mine is the type of isomorphisms -- equivalences between two types:例如,我最喜欢的类型是同构类型——两种类型之间的等价:

data Iso a b = Iso (a -> b) (b -> a)

Iso isn't even a Functor (a prerequisite of Applicative ), but it is still quite useful. Iso甚至不是FunctorApplicative的先决条件),但它仍然非常有用。 It turns out that pairs are equivalent to functions from Bool .事实证明,pairs 等价于Bool中的函数。 We could construct such an equivalence as an Iso value:我们可以将这样的等价构造为Iso值:

pairEquiv :: Iso (a,a) (Bool -> a)
pairEquiv = 
    Iso (\(x,y) -> \b -> if b then x else y) -- from pair to function
        (\f -> (f True, f False))            -- from function to pair

Here (Bool -> a) appears as an argument to a type constructor, and it just means that if you give the Iso a pair, it will give you a function back, and vice versa.这里(Bool -> a)作为类型构造函数的参数出现,它只是意味着如果你给Iso一对,它会给你一个 function 回来,反之亦然。

You can imagine f (a -> b) as a function of type a -> b wrapped in a context.您可以将f (a -> b)想象为包装在上下文中的a -> b类型的 function。 It is mostly used in the context of Applicative s, that Maybe a is a prominent example for.它主要用于Applicative的上下文中, Maybe a就是一个突出的例子。

Applicative s are an extension of Functor s. ApplicativeFunctor的扩展。 A typical example for using Applicative s are functions with multiple arguments.使用Applicative的典型示例是具有多个 arguments 的函数。

What if we have two Maybe Int s that we want to add up.如果我们有两个想要相加的Maybe Int怎么办。 We could try by partially applying + with fmap aka <$> .我们可以尝试通过fmap aka <$>部分应用+ Thus we might try:因此我们可以尝试:

f :: Maybe (Int -> Int)
f = (+) <$> Just 3

But now, how do we apply this to a second argument.但是现在,我们如何将其应用于第二个论点。 That's where we need the Applicative typeclass.这就是我们需要Applicative类型类的地方。 It defines the <*> function.它定义了<*> function。 It has the type它有类型

<*> :: Applicative f => f (a -> b) -> f a -> f b

Thus we can use it to apply a second Maybe Int to our partially applied function f by doing:因此,我们可以使用它对我们部分应用的 function f应用第二个Maybe Int ,方法是:

> f <*> Just 4
Just 7

Without the helper function f the syntax resembles standard function application:如果没有帮助器 function f ,语法类似于标准 function 应用程序:

> (+) <$> Just 3 <*> Just 4
Just 7

For further reference see the chapter on applicative functors of learnyouahaskell.如需进一步参考,请参阅关于 learnyouahaskell 的应用函子的章节。

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

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