right-applied 组合运算符的使用是否暗示可以使用 contramap?

Does the usage of right-applied composition operator hint that contramap could be used?

长话短说

当我发现自己正在编写类似 (. f) . g 的代码时,我正在考虑是否应该考虑使用 contramap,其中 f 实际上是在预处理 [=17] 的第二个参数=].

长话短说

我将描述我是如何想出让我想到标题中的问题的代码的。

最初,我有两个输入,a1 :: Ina2 :: In,包裹在一对 (a1, a2) :: (In,In) 中,我需要对这些输入进行两个交互处理。具体来说,我有一个函数 binOp :: In -> In -> Mid 来生成一个“临时”结果,还有一个函数 fun :: Mid -> In -> In -> OutbinOp 输入 输出.

考虑到上面“由另一个函数的输入和输出提供的函数”部分,我虽然使用了函数 monad,所以我想到了这个,

finalFun = uncurry . fun =<< uncurry binOp

读起来不是很复杂:binOp 将输入作为一对,并将其输出和输入传递给 fun,后者也将输入作为一对。

但是,我注意到在 fun 的实现中我实际上只使用了输入的“简化”版本,即我有一个像 fun a b c = fun' a (reduce b) (reduce c) 这样的定义,所以我认为,在 finalFun 的定义中,我可以使用 fun'reduce 来代替 fun;我想到了

finalFun = (. both reduce) . uncurry . fun' =<< uncurry binOp

这远没有那么容易阅读,尤其是因为它具有 un-natural 部件顺序,我相信。我只能想到使用一些更具描述性的名称,如

finalFun = preReduce . uncurry . fun' =<< uncurry binOp
    where preReduce = (. both reduce)

因为 preReduce 实际上是 pre-processing fun' 的第二个和第三个参数,我在想现在是否是使用 contramap.[=35 的正确时机=]

lmap f . g (, as that would also require an Op wrapper) might indeed be an improvement over (. f) . g in terms of clarity. If your readers are familiar with Profunctor, seeing lmap will promptly suggest the input to something is being modified, without the need for them to perform dot plumbing in their heads. Note it isn't a widespread idiom yet, though. (For reference, here are Serokell Hackage Search queries for the lmap version and the dot section one.)

至于你更长的例子,惯用的做法可能不是将它写成 pointfree。也就是说,我们可以通过更改 fun/fun' 的参数顺序来获得更具可读性的 pointfree 版本,这样您就可以使用 Applicative 实例而不是 Monad一个:

binOp :: In -> In -> Mid
fun' :: In -> In -> Mid -> Out
reduce :: In -> In

both f = bimap f f

finalFun :: (In, In) -> Out
finalFun = uncurry fun' . both reduce <*> uncurry binOp

Pointfree 函数 (<*>) 可以说比 pointfree 函数 (=<<) 更容易理解,因为它的两个参数是相关函数函子中的计算。此外,此更改消除了对点部分技巧的需要。最后,由于 (.) 是函数的 fmap,我们可以进一步将 finalFun 改写为...

finalFun = uncurry fun' <$> both reduce <*> uncurry binOp

... 从而得到一个应用风格的表达式,在我(不太流行!)看来,这是使用函数应用的一种合理可读的方式。 (我们可能会使用 liftA2 进一步简化它,但我觉得在这种特定情况下,发生的事情不太明显。)