4

您能否向我解释以下表达式的工作原理:

str a b = ((.).(.)) (0 -) (+) 1 2

我已经检查过了,GHCi 说是这样,-3但我不明白为什么。

我还检查了以下内容:

*Main> :t ((.).(.))
((.).(.)) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c

但这对我没有帮助。

任何想法?

4

3 回答 3

9

The operator (.).(.) is sometimes given an alias:

(.:) = (.).(.)

You can view it as (.), only it works when the second function takes two arguments. So this works, for example:

sqrtsum = sqrt .: (+)
-- sqrtsum 4 5 ==> 3.0

This will take two numbers, sum them and then take the square root of the sum. The .: alias sort of makes visual sense, as you can imagine the colon representing the function of two arguments being connected to the function of one argument.

If you want to, you can view the type signature of (.) like this:

(.) :: (b -> c) -> (a -> b) -> (a -> c)

This means that (.) takes two functions a -> b and b -> c and "pipes them together" and returns a function from a directly to c. The operator (.:) works similarly – you can write its type signature as

(.:) :: (b -> c) -> (a1 -> a2 -> b) -> (a1 -> a2 -> c)

What it does is that it takes one function a1 -> a2 -> b and one function b -> c and it gives you back a function that goes directly from a1 and a2 to c.

If you want to verify this type for yourself, you can work your way to (.:) with the signature for (.). I will not do this for you, in part because it might end up being a wall of text and in part because it's a great exercise for you in reasoning about your code! If you need a place to start, remember that

(.) :: (b -> c) -> (a -> b) -> (a -> c)

In the expression

(.).(.)

which can also be written as

(.) (.) (.)

the two argument functions to (.) (a -> b and b -> c) are both (.) themselves – so you get to replace a lot of as and bs and cs with what they really represent!

于 2013-08-30T15:52:58.033 回答
8

如果您手动扩展 lambda 项,您将学到最多。或者,如果您很懒惰,请使用工具

无论如何,这里是:

dot = λf.λg.λx.f (g x)

dot dot dot (0 -) + 1 2
⇒   (λg.λx.dot (g x)) dot (0 -) + 1 2
⇒   (λx.dot (dot x)) (0 -) + 1 2
⇒   dot (dot (0 -)) + 1 2
⇒   (λg.λx.dot (0 -) (g x)) + 1 2
⇒   (λx.dot (0 -) (+ x)) 1 2
⇒   dot (0 -) (+ 1) 2
⇒   (λg.λx.0 - (g x)) (+ 1) 2
⇒   (λx.0 - (+ 1 x)) 2
⇒   0 - (+ 1 2)
⇒   0 - 3
于 2013-08-30T11:46:27.257 回答
7

类型:(b -> c) -> (a -> a1 -> b) -> a -> a1 -> c

价值观:(0 -)_______(+)_______________1___2

1 是2aa1..适用于 1 和 2 你得到 3 现在是 的值。(+)(a -> a1 -> b)(+)b

(0 -)(b -> c),将 3(b上面)应用于此,您将得到 (0-3) 即-3它的值,c并且整个函数返回,c因此 -3 是最终答案。

于 2013-08-30T11:26:00.310 回答