[英]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
b
与e -> 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
a
与h -> 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
e
是g -> h
f
is g -> i
f
是g -> 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
替换e
和f
: (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 ~ h
, e ~ 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.