Haskell 带中缀符号的无点样式

Haskell 带中缀符号的无点样式,haskell,pointfree,Haskell,Pointfree,您好,当使用中缀符号时,有没有办法写出无点样式 f::Int->Int->Int->Int f a b=(+) (a+b) 为什么你不能做这样的事 f::Int->Int->Int->Int f a b=(a+b) + or f a b= (a+b) `+` 不能以无点样式组合运算符,例如 ptfree::Int->Int->Int->Int ptfree=(+) (+) 我的意思是,你可以切掉函数的参数,比如折叠

您好,当使用中缀符号时,有没有办法写出无点样式

f::Int->Int->Int->Int
f a b=(+) (a+b)
为什么你不能做这样的事

 f::Int->Int->Int->Int
 f a b=(a+b) +

      or

 f a b= (a+b) `+`
不能以无点样式组合运算符,例如

ptfree::Int->Int->Int->Int
ptfree=(+) (+)
我的意思是,你可以切掉函数的参数,比如折叠,但是为什么不切掉运算符参数呢?

你必须用
(+)
组合两次
(+)
,这样才能完全无点:
f=(+))。(+)

回想一下,组合的定义是

(f . g) x = f (g x)
或者,相当于:

(f . g) = \x -> f (g x)
因此,如果你看一下组合
f=(+)。(+)
并使用
()
的定义向后工作:

你看,在我们试图让它无点指向之前,我们就开始了,所以我们知道这个定义是有效的。通过以上步骤的另一种方式,大致从下到上,可以让您了解如何找到像
f
这样的函数的无点定义

当您像这样从“end”中“off”多个参数时,通常必须多次编写。使用一些类似的函数应该有助于建立对此的直觉


注意:我一般不建议在生产代码中使用这种无点操作(当它使事情复杂化时)。

既然您需要传递两个参数,我们可以使用所谓的“惊奇猫头鹰操作符”。这基本上是由参数组成的。因此,我们可以使用:

f = ((.).(.)) (+) (+)
owl操作符
(.(.)f g
基本上是
\x y->f(g x y)

这是如何工作的?

“惊奇猫头鹰操作符”的标准形式是:

因此,我们现在可以用相应的lambda表达式替换
(.)
s:

(\f g x -> f (g x)) (.) (.)
现在我们可以进行一些替换:

   (\f g x -> f (g x)) (.) (.)
-> (\x -> (.) ((.) x))
-> (\x -> (\q r y -> q (r y)) ((.) x))
-> (\x -> (\r y -> ((.) x) (r y)))
-> (\x r y -> ((.) x) (r y))
-> (\x r y -> ((\s t u -> s (t u)) x) (r y))
-> (\x r y -> (\t u -> x (t u)) (r y))
-> (\x r y -> (\u -> x ((r y) u)))
-> \x r y u -> x ((r y) u))
-> \x r y u -> x (r y u)
所以基本上这意味着我们惊讶的猫头鹰操作符,等于:

surprised_owl :: (y -> z) -> (a -> b -> y) -> a -> b -> z
surprised_owl f g x y = f (g x y)  -- renamed variables
如果我们现在用提供的函数专门化它(两次
(+)
),我们会得到:

因此:


你是说完全免费吗?你给出的唯一一个完全没有点的例子是最后一个。是的,你能做到完全没有点吗?最后三个例子你打算做什么?根据类型签名,它们只接受2个参数。对不起,我编辑了!谢谢你的回答,先生!谢谢你的回答!
(\f g x -> f (g x)) (.) (.)
   (\f g x -> f (g x)) (.) (.)
-> (\x -> (.) ((.) x))
-> (\x -> (\q r y -> q (r y)) ((.) x))
-> (\x -> (\r y -> ((.) x) (r y)))
-> (\x r y -> ((.) x) (r y))
-> (\x r y -> ((\s t u -> s (t u)) x) (r y))
-> (\x r y -> (\t u -> x (t u)) (r y))
-> (\x r y -> (\u -> x ((r y) u)))
-> \x r y u -> x ((r y) u))
-> \x r y u -> x (r y u)
surprised_owl :: (y -> z) -> (a -> b -> y) -> a -> b -> z
surprised_owl f g x y = f (g x y)  -- renamed variables
f = surprised_owl (+) (+)
f x y = (+) ((+) x y)