[英]Find Haskell functions f, g such that f g = f . g
While learning Haskell, I came across a challenge to find two functions f
and g
, such that fg
and f . g
在学习Haskell时,我遇到了一个挑战,找到两个函数f
和g
,比如fg
和f . g
f . g
are equivalent (and total, so things like f = undefined
or f = (.) f
don't count). f . g
是等价的(总和,所以f = undefined
或f = (.) f
不算数)。 The given solution is that f
and g
are both equal to \\x -> x . x
给定的解决方案是f
和g
都等于\\x -> x . x
\\x -> x . x
(or join (.)
). \\x -> x . x
(或join (.)
)。
(I note that this isn't Haskell-specific; it can be expressed in pure combinatory logic as "find f
and g
such that fg = B fg
", and the given solution would then translate to f = g = WB
.) (我注意到这不是Haskell特有的;它可以用纯组合逻辑表示为“找到f
和g
使得fg = B fg
”,然后给定的解将转换为f = g = WB
。)
I understand why the given solution works when I expand it out, but I don't understand how you'd ever find it if you didn't already know it. 我明白为什么给定的解决方案在扩展时会起作用,但我不明白你如何找到它,如果你还不知道的话。 Here's how far I can get: 这是我能走多远:
fg = f . g
fg = f . g
(given) fg = f . g
(给定) fgz = (f . g) z
(eta-expansion of both sides) fgz = (f . g) z
(双方的fgz = (f . g) z
扩张) fgz = f (gz)
(simplify the RHS) fgz = f (gz)
(简化RHS) And I don't know how to proceed from there. 而且我不知道如何从那里开始。 What would I do next in trying to find a solution? 在尝试寻找解决方案时,我会做什么?
I discovered that it's possible to find a family of solutions by considering Church numeral calculation. 我发现通过考虑教会数字计算可以找到一系列解决方案。 In the Church encoding, multiplication is performed by composing the Church numerals, and exponentiation is performed by applying the base to the exponent. 在教会编码中,通过组合教会数字来执行乘法,并且通过将基数应用于指数来执行取幂。 Thus, if f
is the Church encoding of some number x
, and g
is the Church encoding of some number y
, then fg = f . g
因此,如果f
是某个数字x
的Church编码,并且g
是某个数字y
的Church编码,则fg = f . g
fg = f . g
implies y^x = x*y
. fg = f . g
表示y^x = x*y
。 Any nonnegative integer solutions to this equation translate to solutions to the original problem. 该等式的任何非负整数解都转化为原始问题的解。 Examples: 例子:
x=1, y=0, f=id, g=const id
x=1, y=1, f=id, g=id
x=1, y=2, f=id, g=join (.)
y^1 = y = 1*y
for all y
, it makes sense that f=id
works for all Church numerals g
. 由于对于所有y
, y^1 = y = 1*y
,因此f=id
适用于所有教会数字g
是有意义的。 This is indeed the case, and in fact, as Rein Henrichs pointed out, it's true for all g
, and this is easily verifiable by inspection. 这的确是这样的,而事实上,正如雷恩Henrichs指出,这是适用于所有g
,而这是通过检查容易证实。 x=2, y=0, f=join (.), g=const id
x=2, y=2, f=join (.), g=join (.)
x=3, y=0, f=(.) <*> join (.), g=const id
0^x = 0 = x*0
for all positive x
, it makes sense that g=const id
works for all positive Church numerals f
. 由于对于所有正x
, 0^x = 0 = x*0
,因此g=const id
适用于所有正数教会数字f
。 (It does not work for f=const id
, Church numeral 0, which makes sense since 0^0
is an indeterminate form.) (它不适用于f=const id
,教会数字0,这是有道理的,因为0^0
是一个不确定的形式。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.