简体   繁体   English

如何在Haskell中自由地实现f(gx)(hx)?

[英]How to implement f (g x) (h x) point-freely in Haskell?

From this answer one learns how to implement the function \\xyz -> fx (gyz) in a pointless way in Haskell, where f and g are functions. 这个答案中,我们将学习如何在Haskell中无意义地实现函数\\xyz -> fx (gyz) ,其中fg是函数。 And my question is 我的问题是

How to write the function \\x -> f (gx) (hx) in a pointfree manner in Haskell? 如何在Haskell中以无点方式编写函数\\x -> f (gx) (hx) Here f g h are functions for which f (gx) (hx) is defined. f g h是定义f (gx) (hx)的函数。

The idea I currently have in mind is something like the following. 我目前想到的想法如下。

uncurry f (mapTuple ($ x) (g, h))

But several tries shows that this is fallacious; 但是,几次尝试表明这是错误的。 even the part map ($ x) [g, h] is suspicious: what if g and h have different ranges? 甚至零件map ($ x) [g, h]也可疑:如果gh具有不同的范围怎么办?

In addition, readability is not too much an issue here. 另外,可读性在这里不是太大的问题。

Any help is sincerely appreciated. 真诚的感谢您的帮助。

The arrow version would be 箭头版本为

uncurry f . (g &&& h)

or 要么

(g &&& h) >>> uncurry f

As a diagram: 如图所示:

        g ────
       ╱          ╲
──── &&&      >>>  uncurry f ───
       ╲          ╱
        h ──── 

As melpomene suggested, \\x -> f (gx) (hx) is equivalent to liftM2 fgh . 正如melpomene建议的那样, \\x -> f (gx) (hx)等同于liftM2 fgh

When you have question concerning how to convert Haskell code into pointfree Haskell code, you can just try Pointfree.io . 如果您对如何将Haskell代码转换为无点Haskell代码有疑问,可以尝试Pointfree.io

It is a great tool which often can tell you when NOT to use pointfree code because it goes completely unreadable sometimes :-) 它是一个很棒的工具,通常会告诉您何时不使用无点代码,因为有时它会变得完全不可读:-)

在此处输入图片说明

Applicative-style 适用风格

f <$> g <*> h

Control.Compose 控制组成

join ((g ~> h ~> id) f)

Data.Function.Meld 数据功能合并

join (f $* g $$ h *$ id)

Data.Function.Tacit 数据功能默认

lurryA @N1 (f <$> (g <$> _1) <*> (h <$> _1))
lurryA @N4 (_1 <*> (_2 <*> _4) <*> (_3 <*> _4)) f g h

This only serves to collect and put into order the answers in the comments. 这仅用于收集和整理评论中的答案。 According to the abstraction-elimination process in the link in the comment by @ PetrPudlák, we can also write 根据@PetrPudlák评论中的链接中的抽象消除过程,我们还可以编写

S (S (K f) (S (K g) I)) (S (K h) I),

or, after eta reduction, 或者,经过eta减少后,

S (S (K f) g) h,

where 哪里

S x y z = x z (y z)
K x y = x

Specifically in Haskell, thanks to @melpomene for pointing this out, the role of S is played by ap , and that of K by const . 特别是在Haskell中,感谢@melpomene指出了这一点, S的角色由ap扮演, K的角色由const扮演。 Therefore we can write 因此我们可以写

ap (ap (const f) g) h

In fact we can further reduce: 实际上,我们可以进一步减少:

ap (const f) g = f . g

So our function can be written as: 所以我们的函数可以写成:

ap (f . g) h

If translated to Applicative style, we obtain: 如果转换为应用风格,我们将获得:

f <$> g <*> h

Then this systematic approach can be applied to all lambda terms, and gives the point-free style. 然后可以将此系统化方法应用于所有lambda项,并给出无点样式。 :) :)

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

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