【问题标题】:Cartesian product not working for applicative笛卡尔积不适用于应用程序
【发布时间】:2019-04-20 20:57:22
【问题描述】:

我试图了解 applicative 以及如何将其用作 K 函数和 N 参数之间的笛卡尔积,但我无法理解为什么我不能执行以下操作:

[Just (+1),Just (+2)] <*> [Just 1 ,Just 2] 渲染

错误

* Couldn't match expected type `Maybe Integer -> b'
                  with actual type `Maybe (Integer -> Integer)'
    * Possible cause: `Just' is applied to too many arguments      In the expression: Just (+ 1)      In the first argument of `(<*>)', namely `[Just (+ 1), Just (+ 2)]'
      In the expression: [Just (+ 1), Just (+ 2)] <*> [Just 1, Just 2]

我不明白,因为根据定义,它应该将函数从上下文中取出,取值并应用所有组合。

我也试过了:

有人能解释一下吗?

【问题讨论】:

  • 上下文(在本例中为[])不包含函数。它包含Maybes。所以试图在上下文中应用函数是一个类型错误。这就是为什么错误说它需要一个函数但实际上得到了一个Maybe。请改用[(+1), (+2)] &lt;*&gt; [1,2]
  • 这里有两个级别的函子:一个列表和一个Maybe
  • 您是否故意尝试组合两个应用程序[]Maybe?如果是这样,那么默认情况下这将不起作用,因为 GHC 不了解您正在使用组合。您需要为组合创建一个新类型,可以使用Compose 或使用newtype MaybeList a = [Maybe a] 之类的“手动”(然后为MaybeList 提供您自己的Applicative 实例)。

标签: haskell cartesian-product applicative


【解决方案1】:

这里涉及到两个应用层([]Maybe),所以(&lt;*&gt;) 本身必须被应用:

GHCi> (<*>) <$> [Just (+1),Just (+2)] <*> [Just 1 ,Just 2]
[Just 2,Just 3,Just 3,Just 4]

此用例由 Compose 新类型捕获。 Nesting any two applicative functors gives rise to another applicative:

GHCi> import Data.Functor.Compose
GHCi> Compose [Just (+1),Just (+2)] <*> Compose [Just 1 ,Just 2]
Compose [Just 2,Just 3,Just 3,Just 4]

.

【讨论】:

  • 您能否详细说明&lt;$&gt; 在这种情况下是如何工作的?你有一个f g (k::a-&gt;a)f g a。所以你有两个函子fg。你有一个a 和一个a-&gt;a。我不明白你如何在第一种情况下使用(&lt;*&gt;) &lt;$&gt; 解开函子。
  • @BercoviciAdrian 在这个例子中,第一个列表是[Maybe (Integer -&gt; Integer)](&lt;$&gt;) 映射通过列表层(但不是 Maybe 之一)。我们有(&lt;*&gt;) :: Applicative f =&gt; f (a -&gt; b) -&gt; (f a -&gt; f b),所以第一个(&lt;*&gt;) 专门用于Maybe (Integer -&gt; Integer) -&gt; (Maybe Integer -&gt; Maybe Integer)——我们(部分)将(&lt;*&gt;) 应用于第一个列表中的Maybe值。既然如此,(&lt;*&gt;) &lt;$&gt; [Just (+1),Just (+2)] 最终会成为[Maybe Integer -&gt; Maybe Integer],这是您需要与第二个(&lt;*&gt;) 一起使用的内容(与(&lt;$&gt;) 一样,使用列表Applicative)。
  • 但我不明白为什么不使用 &lt;$&gt; 就不能解包。我的意思是 (&lt;*&gt;) [Just (+1)] 意味着你绑定第一个参数,然后你可以只提供值一个。您的通用参数变为a=Maybe a
  • @BercoviciAdrian 为此,Just (+1) 必须是一个函数,但它不是一个函数(它是一个包含函数的 Maybe-值)。 (&lt;*&gt;) 只能通过一个应用层工作;这就是为什么我们需要第二个(&lt;*&gt;)。 (另一种方法是使用Compose 将两层作为一个处理。)
猜你喜欢
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-15
  • 2013-12-25
  • 2013-07-14
相关资源
最近更新 更多