简体   繁体   English

应用程序上的多个 arguments 不起作用?

[英]Multiple arguments on applicatives not working?

So I'm trying to learn about monads, functors and applicatives.所以我正在尝试学习单子、函子和应用程序。 I've created the following renamed mirror match of Maybe called Sometimes .我创建了以下重命名的Maybe镜像匹配,称为Sometimes (I did this to learn about these things) (我这样做是为了了解这些事情)

data Sometimes a = Nope | Thing a deriving Show

instance Monad Sometimes where
    (Thing x) >>= f = f x
    Nope  >>= f = Nope
    return      = Thing

instance Applicative Sometimes where
      pure = Thing
      Nope <*> _ = Nope
      (Thing g) <*> mx = fmap g mx

instance Functor Sometimes where
     fmap _ Nope = Nope
     fmap g (Thing x) = Thing (g x)

So when I do the following it works:因此,当我执行以下操作时,它会起作用:

pure (1+) <*> (Thing 1)
> Thing 2

pure (+) <*> (Thing 1) <*> (Thing 1)
> Thing 2

But if I try three additions it doesn't work:但是如果我尝试三个添加它不起作用:

pure (+) <*> (Thing 1) <*> (pure 1) <*> (pure 1)

<interactive>:108:1: error:
    • Non type-variable argument in the constraint: Num (a -> b)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall a b. (Num (a -> b), Num a) => Sometimes b

Why doesn't this work?为什么这不起作用? I would expect the first two to be applied and then the third to be applied to the result of the first two.我希望前两个被应用,然后第三个被应用到前两个的结果。 My book talks about how implementing fmap0, fmap1, fmap2... is inefficient and as such我的书谈到了如何实现fmap0, fmap1, fmap2...是低效的,因此

... for functions with any desired number of arguments can be constructed in terms of two basic functions with the following types: pure:: a -> fa (<*>):: f (a -> b) -> fa -> fb ...对于具有任何所需数量的 arguments 的函数,可以根据具有以下类型的两个基本函数构造: pure:: a -> fa (<*>):: f (a -> b) -> fa -> fb

And states further on:并进一步说明:

A typical use of pure and <*> has the following form: pure<*>的典型用法如下:

 pure g <*> x1 <*> x2 <*>... <*> xn

As such I'm expecting it to work but I'm clearly missing something in my definitions/usage of the Applicative .因此,我希望它能够工作,但我显然在Applicative的定义/使用中遗漏了一些东西。


I'm using the book Programming in Haskell SE by Graham Hutton我正在使用 Graham Hutton 的 Haskell SE 编程一书

The reason this does not work is because (+) sums two numbers, not three.这不起作用的原因是因为(+)将两个数字相加,而不是三个。

You can make a function that sums three numbers, for example with:您可以制作一个对三个数字求和的 function,例如:

pure (\x y z -> x+y+z) <*> (Thing 1) <*> (pure 1) <*> (pure 1)

this then gives us:这给了我们:

Prelude> pure (\x y z -> x+y+z) <*> (Thing 1) <*> (pure 1) <*> (pure 1)
Thing 3

Why doesn't this work?为什么这不起作用? I would expect the first two to be applied and then the third to be applied to the result of the first two.我希望前两个被应用,然后第三个被应用到前两个的结果。

Exactly , but after the first two are applied, this is no longer a function, but a Num a => Sometimes a .没错,但是在应用了前两个之后,这不再是 function,而是Num a => Sometimes a Indeed, if we determines the types, we see that Thing (+):: Num a => Sometimes (a -> a -> a) and Thing 1:: Num b => Sometimes b , so that means that Thing (+) <*> Thing 1 has type Num a => Sometimes (a -> a) .确实,如果我们确定类型,我们会看到Thing (+):: Num a => Sometimes (a -> a -> a)Thing 1:: Num b => Sometimes b ,所以这意味着Thing (+) <*> Thing 1的类型为Num a => Sometimes (a -> a)

Then we determine the type of Thing (+) <*> Thing 1 <*> Thing 1 , since Thing (+) <*> Thing 1 has type Num a => Sometimes (a -> a) , and the last Thing 1 has type Num c => Sometimes c , it means that Thing (+) <*> Thing 1 <*> Thing 1 has type Num a => Sometimes a , but this is not a function, unless there is a Num type that is a function, which is what the error is saying.然后我们确定Thing (+) <*> Thing 1 <*> Thing 1的类型,因为Thing (+) <*> Thing 1具有类型Num a => Sometimes (a -> a) ,最后一个Thing 1具有类型Num c => Sometimes c Thing (+) <*> Thing 1 <*> Thing 1 Num a => Sometimes a Num一个 function,这就是错误的意思。

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

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