内部具有幺半群和函数的元组的应用实例

fol*_*one 9 scala scalaz applicative monoids

我试图将一个haskell示例(我之前遇到过)转换为scalaz.最初的例子如下:

("Answer to the ", (*)) <*> ("Ultimate Question of ", 6) <*> ("Life, the Universe, and Everything", 7)
Run Code Online (Sandbox Code Playgroud)

据我所知,使用实例.

它没有按字面意思转换为scalaz:

scala> ("Answer to the ", ((_: Int) * (_: Int)) curried) |@| ("Ultimate Question of ", 6) |@| ("Life, the Universe, and Everything", 7) tupled
res37: (java.lang.String, (Int => (Int => Int), Int, Int)) = (Answer to the Ultimate Question of Life, the Universe, and Everything,(<function1>,6,7))
Run Code Online (Sandbox Code Playgroud)

虽然,我已经找了一个实例,它似乎在那里(再次,据我所知).

所以,问题是:为什么它不能像这样工作?或者我错过了什么/没有得到正确的答案?

Tra*_*own 5

Scalaz中的等价物Control.Applicative<*>也叫<*>,虽然它混淆的接受它的参数以相反的顺序.以下是有效的:

val times = ((_: Int) * (_: Int)) curried
val a = "Answer to the "
val b = "Ultimate Question of "
val c = "Life, the Universe, and Everything"

(c, 7) <*> ((b, 6) <*> (a, times))
Run Code Online (Sandbox Code Playgroud)

或者,正如我在回复您的评论时所指出的那样,如果您想坚持下去,可以使用以下内容|@|:

(a -> times |@| b -> 6 |@| c -> 7)(_ apply _ apply _)
Run Code Online (Sandbox Code Playgroud)

我个人更喜欢这个<*>版本,即使它感觉倒退.


我们可以更详细地了解正在发生的事情.首先,你并不需要的全部功能Applicative这里- Apply会做.我们可以Apply使用implicitly以下命令获取元组的实例:

scala> val ai = implicitly[Apply[({type ?[?]=(String, ?)})#?]]
ai: scalaz.Apply[[?](java.lang.String, ?)] = scalaz.Applys$$anon$2@3863f03a
Run Code Online (Sandbox Code Playgroud)

现在我们可以将第一个元组应用到第二个元组:

scala> :t ai(a -> times, b -> 6)
(java.lang.String, Int => Int)
Run Code Online (Sandbox Code Playgroud)

结果到了第三个:

scala> :t ai(ai(a -> times, b -> 6), c -> 7)
(java.lang.String, Int)
Run Code Online (Sandbox Code Playgroud)

这是我们想要的:

scala> ai(ai(a -> times, b -> 6), c -> 7)._1
res0: java.lang.String = Answer to the Ultimate Question of Life, the Universe, and Everything

scala> ai(ai(a -> times, b -> 6), c -> 7)._2
res1: Int = 42
Run Code Online (Sandbox Code Playgroud)

这个<*>方法MA可以更好地包装它.