所以我知道:
(.) = (f.g) x = f (g x)
它的类型是(B-> C) - >(A-> B) - > A-> C,但怎么样:
(.)(.) = _? = _?
这是如何表示的? 我认为:
(.)(.) = (f.g)(f.g)x = f(g(f(g x))) // this
(.)(.) = (f.g.h)x = f(g(h x)) // or this
但据我试图得到它的类型,这是不正确的东西GHCI告诉我。 那么,什么都是“_?”
此外-这是什么功能/操作$吗?
首先,你做事马虎你的符号。
(.) = (f.g) x = f (g x) -- this isn't true
什么是正确的:
(.) f g x = (f.g) x = f (g x)
(.) = \f g x -> f (g x)
而其类型由给定
(.) :: (b -> c) -> (a -> b) -> a -> c
-- n.b. lower case, because they're type *variables*
与此同时
(.)(.) :: (a -> b -> d) -> a -> (c -> b) -> c -> d
-- I renamed the variables ghci gave me
现在,让我们锻炼身体
(.)(.) = (\f' g' x' -> f' (g' x')) (\f g x -> f (g x))
= \g' x' -> (\f g x -> f (g x)) (g' x')
= \g' x' -> \g x -> (g' x') (g x)
= \f y -> \g x -> (f y) (g x)
= \f y g x -> f y (g x)
= \f y g x -> (f y . g) x
= \f y g -> f y . g
和($)
($) :: (a -> b) -> a -> b
f $ x = f x
($)
仅仅是功能应用。 但是,尽管通过并列功能的应用是高优先级,功能应用通过($)
为低优先级。
square $ 1 + 2 * 3 = square (1 + 2 * 3)
square 1 + 2 * 3 = (square 1) + 2 * 3 -- these lines are different
作为dave4420提到,
(.) :: (b -> c) -> (a -> b) -> a -> c
那么什么是类型(.) (.)
dave4420跳过该部分,因此在这里它是: (.)
接受类型的值b -> c
作为第一个参数,所以
(.) :: ( b -> c ) -> (a -> b) -> a -> c
(.) :: (d -> e) -> ((f -> d) -> f -> e)
因此,我们有b ~ d->e
和c ~ (f -> d) -> f -> e
,并且将所得的式(.)(.)
是(a -> b) -> a -> c
。 代,我们得到
(a -> d -> e) -> a -> (f -> d) -> f -> e
重命名,我们得到(a -> b -> c) -> a -> (d -> b) -> d -> c
。 这是一个函数f
期望一个二进制函数g
,值x
,一元函数h
和另一个值y
:
f g x h y = g x (h y)
这是这种类型的,可实现的唯一途径: gx :: b -> c
, hy :: b
等gx (hy) :: c
,根据需要。
在Haskell当然,“一元”的功能是这样的,期望一个或多个参数; 类似地一个“二进制”功能是这样的,需要两个或更多的参数。 但不得少于两(因此使用如succ
是不可能的)。
我们也可以通过写方程解决这个问题, 组合子式的 1。 等式推理是很容易 :
(.) (.) x y z w q =
((.) . x) y z w q =
(.) (x y) z w q =
(x y . z) w q =
x y (z w) q
我们只是扔根据需要到混合尽可能多的变量,然后应用定义来回。 q
这里是一个额外的,所以我们可以把它扔掉,并获得最终的定义,
_BB x y z w = x y (z w)
(巧合的是, (.)
被称为乙 -combinator )。
1个 abc = (\x -> ... body ...)
相当于abcx = ... body ...
,反之亦然,条件是x
并不之间出现{a,b,c}