haskell - 适用于 <$> 和 <*> 的运算符部分

标签 haskell applicative operator-sections

考虑类型为 a -> b -> c 的函数,以及应用值 a1, a2::(Applicative f) => f a

我希望构造一个可以应用于 a -> b -> c 类型的函数来获取 Applicative f::f c 类型的值的函数。我可以通过以下方式做到这一点:

g :: (Applicative f) => (a -> b -> c) -> f c
g = \f -> f <$> a1 <*> a2

(显式 lambda 是经过深思熟虑的,因为我正在考虑在任何级别构建此函数,而不仅仅是顶层)。

如果我尝试以无点样式编写 g:

g = (<$> a1 <*> a2)

我收到以下编译错误:

The operator `<$>' [infixl 4] of a section
    must have lower precedence than that of the operand,
      namely `<*>' [infixl 4]
    in the section: `<$> gen1 <*> gen2'

可以编写这个无点实现:

g = flip (flip liftA2 a1) a2

但我觉得这可读性较差,并且重构基于中缀函数的实现(例如添加另一个参数)比更改上面的内容以使用 liftA3 更简单。

一个人可以写出一系列的作品:

g = (<*> a2) . (<$> a1)

这实现了无点样式,并且添加参数很简单 - 但它们前置在左侧而不是附加在右侧,因此您失去了与函数类型的对应关系(a -> b -> c)。此外,如果参数更多,您最终会得到比第一个实现中仅使用 lambda 更长的表达式。

那么,有没有好的、简洁的方式来编写我想要的部分,或者我是否坚持使用 lambda?

最佳答案

<*><$> 的结果进行运算,所以:

g = (<*> a2) . (<$> a1)

关于haskell - 适用于 <$> 和 <*> 的运算符部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30748319/

相关文章:

Haskell 中的函数应用

haskell - 为什么haskell不能推导出这个多参数类型类?

haskell - Yesod 删除级联

haskell - 某些向量运算中没有惰性

scala - 接受两个monadic值并返回一个monadic值的泛型函数

haskell - Reader monad 可以做哪些应用函数不能做的事情?

haskell - 应用程序组成,单子(monad)不

haskell加入多级monad