Rip*_*peR 3 haskell types function-composition operator-keyword
所以我知道:
(.) = (f.g) x = f (g x)
Run Code Online (Sandbox Code Playgroud)
它的类型是(B-> C) - >(A-> B) - > A-> C但是怎么样:
(.)(.) = _? = _?
Run Code Online (Sandbox Code Playgroud)
这是如何表示的?我想到了:
(.)(.) = (f.g)(f.g)x = f(g(f(g x))) // this
(.)(.) = (f.g.h)x = f(g(h x)) // or this
Run Code Online (Sandbox Code Playgroud)
但就我试图获得它的类型而言,GHCi告诉我的不正确.那么什么都是"_?"
另外 - 函数/运算符$做什么?
dav*_*420 14
首先,你的符号很邋..
(.) = (f.g) x = f (g x) -- this isn't true
Run Code Online (Sandbox Code Playgroud)
这是真的:
(.) f g x = (f.g) x = f (g x)
(.) = \f g x -> f (g x)
Run Code Online (Sandbox Code Playgroud)
它的类型由.给出
(.) :: (b -> c) -> (a -> b) -> a -> c
-- n.b. lower case, because they're type *variables*
Run Code Online (Sandbox Code Playgroud)
与此同时
(.)(.) :: (a -> b -> d) -> a -> (c -> b) -> c -> d
-- I renamed the variables ghci gave me
Run Code Online (Sandbox Code Playgroud)
现在让我们解决吧
(.)(.) = (\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
Run Code Online (Sandbox Code Playgroud)
而且($)?
($) :: (a -> b) -> a -> b
f $ x = f x
Run Code Online (Sandbox Code Playgroud)
($)只是功能应用.但是通过并置的功能应用是高优先级,功能应用通过($)优先级低.
square $ 1 + 2 * 3 = square (1 + 2 * 3)
square 1 + 2 * 3 = (square 1) + 2 * 3 -- these lines are different
Run Code Online (Sandbox Code Playgroud)
正如dave4420所提到的,
(.) :: (b -> c) -> (a -> b) -> a -> c
Run Code Online (Sandbox Code Playgroud)
那是什么类型的(.) (.)?dave4420跳过那部分,所以这里是:(.)接受一个类型的值b -> c作为它的第一个参数,所以
(.) :: ( b -> c ) -> (a -> b) -> a -> c
(.) :: (d -> e) -> ((f -> d) -> f -> e)
Run Code Online (Sandbox Code Playgroud)
所以我们有b ~ d->e和c ~ (f -> d) -> f -> e,结果类型(.)(.)是(a -> b) -> a -> c.替代,我们得到
(a -> d -> e) -> a -> (f -> d) -> f -> e
Run Code Online (Sandbox Code Playgroud)
重命名,我们得到(a -> b -> c) -> a -> (d -> b) -> d -> c.这是一个f需要二进制函数g,值x,一元函数h和另一个值的函数y:
f g x h y = g x (h y)
Run Code Online (Sandbox Code Playgroud)
这是可以实现这种类型的唯一方法:g x :: b -> c,h y :: b所以g x (h y) :: 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
Run Code Online (Sandbox Code Playgroud)
我们只需要在混合中输入尽可能多的变量,然后来回应用定义.q这是一个额外的,所以我们可以抛弃它并得到最终的定义,
_BB x y z w = x y (z w)
Run Code Online (Sandbox Code Playgroud)
(巧合的(.)是,被称为B- Combinator).
如果不出现,则1a b c = (\x -> ... body ...)等同于a b c x = ... body ...,反之亦然.x{a,b,c}