简体   繁体   English

haskell中的函数(。)。(。)

[英]The function (.).(.) in haskell

I am trying to find the type of (.).(.) in Haskell, manually. 我试图在Haskell中手动找到(.).(.)的类型。

My attempt was the following: 我的尝试如下:

(.).(.) = \x -> (.).(.) x

(.)     :: (     b   ->             c         )  ->  ((     a    ->           b        ) -> (a -> c))
(.)     :: (d -> e)  ->  ((f -> d) -> (g -> e))
(.)     ::                                              (h -> i) -> (j -> h) -> (h -> k)

-----------------------------------------------------------------------------------------------------
b ~ (d -> e) ~ (j -> h) -> (h -> k)
c ~ ((f -> d) -> (g -> e))
a ~ (h -> i)
d ~ h
e ~ i                 

so (a->c)~     (h->i) -> ((f -> h) -> (g -> i))

What is wrong in my way of thinking? 我的思维方式有什么问题? The actual type is 实际类型是

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

Let's look at the equivalent (.) (.) (.) 让我们看看等效的(.) (.) (.)

The first dot type: (b -> c) -> (a -> b) -> a -> c 第一个点类型: (b -> c) -> (a -> b) -> a -> c

Second: (e -> f) -> (d -> e) -> d -> f 第二个: (e -> f) -> (d -> e) -> d -> f

Hence: 因此:

b is the same as e -> f be -> f相同

c is the same as (d -> e) -> d -> f c(d -> e) -> d -> f

Third: (h -> i) -> (g -> h) -> g -> i 第三: (h -> i) -> (g -> h) -> g -> i

Hence: 因此:

a is the same as h -> i ah -> i相同

b is the same as (g -> h) -> g -> i b(g -> h) -> g -> i

e -> f is (g -> h) -> g -> i e -> f(g -> h) -> g -> i

e is g -> h eg -> h

f is g -> i fg -> i

Since (.) (.) (.) :: a -> c from the first dot type, we have: 由于第一个点类型的(.) (.) (.) :: a -> c ,我们得到:

a -> c is (h -> i) -> (d -> e) -> d -> f a -> c(h -> i) -> (d -> e) -> d -> f

substituting e and f : (h -> i) -> (d -> g -> h) -> d -> g -> I 替换ef(h -> i) -> (d -> g -> h) -> d -> g -> I

Answering your question, I think that what is wrong with your thinking are last two lines eg: 回答您的问题,我认为您的想法出了问题,是最后两行,例如:

d ~ h , e ~ i d ~ he ~ i

Your derivation should have been : 您的推导应该是:

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

(.) :: (   b      ->           c          )  ->  (   a      ->           b          ) -> (a -> c) 
(.) ::  (d -> e)  ->  (f -> d) -> (g -> e)   -- WRONG
(.) ::                                            (h -> i)  ->  (j -> h) -> (h -> k)  -- WRONG
(.) ::  (d -> e)  ->  (f -> d) -> (f -> e)   -- correct
(.) ::                                            (h -> i)  ->  (j -> h) -> (j -> i)  -- correct

Thus the overall type is 因此,总体类型为

(.) (.) (.) ::   a    ->                c                   ,   b ~ b
            ~  (h->i) ->  (f ->   d   ) -> (f ->   e   )    ,   (j -> h) -> (j -> i) ~ 
                                                               (   d     ->    e    )
             --------------------------------------------
               (h->i) ->  (f -> j -> h) -> (f -> j -> i)

Or, 要么,

               (                     h             -> i) 
                      ->  (f -> j -> h)
             --------------------------------------------
                                        -> (f -> j -> i)

The types of such composition chains are often easier to follow with (>>>) = flip (.) : 这样的组成链的类型通常更容易遵循(>>>) = flip (.)

(.) . (.) = comp2  .  comp1
          = comp1 >>> comp2    where   comp1 = (.) ; comp2 = (.)

(>>>)    ::   (  a    ->         b         ) -> 
                        (        b           ->         c         )  ->  (a -> c)
comp1    ::    (e->f) -> ((d->e) -> (d->f))
comp2    ::              (  h    ->   i   )  -> ((g->h) -> (g->i))
-------------------------------------------------------------------------
               (e->f)                        -> ((g->h) -> (g->i))
                         h~(d->e)   i~(d->f)
-------------------------------------------------------------------------
               (e->f) -> (g->d->e) -> (g->d->f)

Thus, again, 因此,再次

((.) . (.)) :: (c->r) -> (a->b->c) -> (a->b->r)
((.) . (.)) f g a b = f (g a b)

Indeed, 确实,

((.) . (.)) f g a b = ((.) . (.)) f  g  a  b
                    =  (.) ( (.)  f) g  a  b
                    =      ((f .)  . g) a  b     -- NB
                    =       (f .)  ( g  a) b
                    =       (f .     g  a) b

                    =        f (     g  a  b)

NB: 注意:


You can also verify that 您还可以验证

((.) . (.) . (.)) :: (d->r) -> (a->b->c->d) -> (a->b->c->r)
((.) . (.) . (.)) f g a b c = f (g a b c)

Why? 为什么? (.) is fmap for functions, and so we can re-write the above as (.)是函数的fmap ,因此我们可以将上面的代码重写为

(fmap . fmap . fmap) f g a b c =
   fmap (fmap (fmap f)) g a b c =
   (do { x <- g ; return $ fmap (fmap f) x }) a b c =
   (do { x <- g ; return $ do { y <- x ; return $ fmap f y } }) a b c =
   (do { x <- g ; return $ do { y <- x ; return $ do { z <- y ; return $ f z } } }) a b c =
   let x=g a in (const $ do { y <- x ; return $ do { z <- y ; return $ f z } }) a b c =
   let x=g a in (do { y <- x ; return $ do { z <- y ; return $ f z } }) b c =
   let x=g a in let y=x b in (const $ do { z <- y ; return $ f z }) b c =
   let x=g a in let y=x b in (do { z <- y ; return $ f z }) c =
   let x=g a in let y=x b in let z=y c in const (f z) c =
   let x=g a in let y=x b in f (y c) =
   let x=g a in f (x b c) =
   f (g a b c)

This obviously works for any number of the chained compositions of fmap s that way. 显然,这适用于fmap的任何数量的链式组合。

The simple definition of compose is: compose的简单定义是:

compose f h x = f (h x)

and its type: 及其类型:

compose :: (t1 -> t2) -> (t3 -> t1) -> t3 -> t2

the type variable name changes because I defined manually. 类型变量名称更改,因为我手动定义了。 So, if you want to compose the compose function, you will need an extra argument, because compose takes a function that takes one argument, so, compose of compose will need an extra argument. 因此,如果要编写compose函数,则将需要一个额外的参数,因为compose接受一个带有一个参数的函数,因此,compose的compose将需要一个额外的参数。 The definition of compose of compose could be simple as: compose的定义很简单:

composeOfCompose f h x y = f (h x y) 

and its type, as you could figure is: 其类型(如您所见)是:

composeOfCompose :: (t1 -> t2) -> (t3 -> t4 -> t1) -> t3 -> t4 -> t2

why is that? 这是为什么? well, follow the application of functions: 好吧,请遵循功能的应用:

x :: t3
y :: t4
h :: t3 -> t4 -> t1
f :: t1 -> t2
composeOfCompose f h :: t3 -> t4 -> t2

if you think it like this is a little simpler, I guess, at least for me. 如果您觉得这样简单一点,我想,至少对我来说。

To add a little more info about it with the question in the comment of DW: 要在DW的注释中添加更多有关该问题的信息,请执行以下操作:

compose :: (t1 -> t2) -> (t3 -> t1) -> t3 -> t2
compose f h x = f (h x)

composeOfCompose :: (t1 -> t2) -> (t4 -> t5 -> t1) -> t4 -> t5 -> t2
composeOfCompose  = compose compose compose

If the first compose is compose' and the second compose is compose'' 如果第一个撰写是compose' ,第二个撰写是compose''

compose' (f' :: (t1 -> t2)) 
         (h' :: (**t3** -> t1)) (x' :: **t3**) = f' (h' x')

and the second should have: 第二个应该具有:

compose'' (f'' :: (t4 -> t5))
          (h'' :: (t6 -> t4)) (x'' :: t6) = f'' (h'' x'')

so... 所以...

**t3** ~ (t4 -> t5)
meaning h :: t4 -> t5 -> t1

translating in place, the middle compose:: 翻译到位,中间组成:

compose f h x = f :: t1 -> t2
                (h :: t4 -> t5 -> t1)
                    (x :: t4 -> t5)) :: t1

A simple example: 一个简单的例子:

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

lets create a function for that: 让我们为此创建一个函数:

composeOfCompose  = (.) . (.)

data A1 = A | B deriving Show
data A2 = C | D deriving Show
data B  = E | F deriving Show
data C  = G | H deriving Show

transform :: A1 -> A2 -> B
transform A C = E
transform B C = E
transform _ _ = F

finalTrans :: B -> C
finalTrans E = G
finalTrans F = H

main = do
  putStrLn $ show $ (composeOfCompose finalTrans transform) A D

$> H

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM