Haskell: 如何compose一个二元函数与一个一元函数

大概是这样的, 逛SO的时候发现了这个帖子, 觉得相当有趣, 大意是要把nub和(++) compose成一个函数, 达到先连接再nub的效果

当然可以

f a b = nub $ a ++ b

但是这样很丑嘛

所以就可以使用

((nub .) .) (++)

于是我们来分析一下类型(为了避免混淆我适当地更改了类型变量名):

(.) :: (b -> c) -> (a -> b) -> (a -> c)
nub :: [a] -> [a]
(++) :: [a] -> [a] -> [a]

(nub .) :: (b -> [a]) -> (b -> [a])

((nub .) .) :: (c -> (b -> [a]) ) -> (c -> (b -> [a]) )

((nub .) .) (++) :: [a] -> ([a] -> [a])

类型演算麻烦就麻烦在要不停地换元容易把自己绕晕了表情

接下来再分析一下curry:

(.) = \f.(\g.(\a.f(ga)))
(++) = \a.(\b.a++b)
nub = \a.nub(a)

(.) nub = (\f.(\g.(\a.f(ga))))nub = \g.(\a.nub(ga)) = \g.(\a.nub(ga))

(.) ((.) nub) = (\f.(\g.(\a.f(ga))))(\g.(\a.nub(ga))) = \h.(\b.(\g.(\a.nub(ga)))(hb)) = \h.(\b.(\a.nub((hb)a)))

((.) ((.) nub)) (++) = (\h.(\b.(\a.nub((hb)a))))(++) = \b.(\a.nub(((++)b)a) = \b.(\a.nub(a++b))

因为lambda calculus还不够熟练所以就把很多中间步骤都写出来了还偷偷换了元orz

似乎要去补一补orz

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s