问题描述
我是 Haskell 的新手.我试图了解类型的组合是如何工作的.
(.) :: (b -> c) ->(a -> b) ->->Cfmap :: 函子 f =>(x -> y) ->f x ->f y地图.fmap :: (Functor f1, Functor f2) =>(x -> y) ->f1 (f2 x) ->f1 (f2 y)
我对上述类型信息的理解如下.
1. (x -> y) ->f1 x ->f1 y -- 第一个 fmap->(x' -> y') ->f2 x' ->f2 y' -- 第二个 fmap2.比较(1)和(.)类型签名,然后我们得到在 (b -> c)b = (x -> y)c = f1 x ->f1 y在 (a -> b)a = (x' -> y')b = f2 x' ->f2 y'3. 现在的结果是 ->c 但在 (b -> c) 中的 b 之前应该是 (a -> b) 中的 b(x -> y) === f2 x' ->f2 y'这意味着 x = f2 x' &y = f2 y'4. 结果是 ->C(x' -> y') ->f1 x ->f1 y将 (3) 结果代入此处(x' -> y') ->f1 (f2 x') ->f1 (f2 y')这是 Alpha 等价于 (x -> y) ->f1 (f2 x) ->f1 (f2 y)为了测试我的理解,我尝试了各种数据类型,但在少数情况下取得了成功.以下是我无法弄清楚的类型签名.
f = 未定义 :: (x -> y -> w -> z -> a) ->g x ->y- f 的类型.f 序曲F .f :: (x -> (w1 -> z1 -> a1) -> w2 -> z2 -> a2) ->g (y -> x) ->y我对上述方法的处理
1.(x -> y -> w -> z -> a) ->g x ->y->(x' -> y' -> w' -> z' -> a') ->g' x' ->g'y'2. 比较 (.) then在 (b -> c)b = (x -> y -> w -> z -> a)c = g x ->y在 (a -> b)a = (x' -> y' -> w' -> z' -> a')b = g' x' ->g'y'3. 比较 b 来自 (b -> c) &(a -> b)(x -> y -> w -> z -> a) === g' x' ->g'y'这意味着 x = g' x' &y ->w->z->a = g'y'4. 结果是 ->C(x' -> y' -> w' -> z' -> a') ->g x ->y现在没有直接的 y 我可以用 g y 代替
我看构图的方法不适合我.
类型派生纯粹是机制 过程.
(.) :: (b -> c ) ->(a -> b ) ->(a -> c)fmap₂ :: 函子 f =>(t3 -> t4) ->(f t3 -> f t4)fmap₁ :: 函子 g =>((t1 -> t2) -> (g t1 -> g t2))-------------------------------------------------------------------------------------------a ~ (t1 -> t2) b ~ (g t1 -> g t2)b ~ (t3 -> t4) c ~ (f t3 -> f t4) b ~ (t3 -> t4)-------------------------------------------------------------------------------------------fmap₂ .fmap₁ :: (Functor f, Functor g)=>->C~ (t1 -> t2) ->(f t3 -> f t4 )~ (t1 -> t2) ->(f(g t1) -> f(g t2))
这对于 (.)
的表亲 (>>>) fmap₁ fmap₂ = fmap₂ 好得多.fmap₁
:
(>>>) :: (a -> b ) ->(b->c)->(a -> c )fmap₁ :: 函子 g =>(t1 -> t2) ->(g t1 -> g t2)fmap₂ :: 函子 f =>(t3->t4)->(f t3 -> f t4)-------------------------------------------------------------------------------a ~ (t1 -> t2) b ~ (g t1 -> g t2)b ~ (t3 -> t4 ) c ~ (f t3 -> f t4)-------------------------------------------------------------------------------fmap₁>>>fmap₂ :: (Functor f, Functor g)=>->C~ (t1 -> t2) ->(f t3 -> f t4 )~ (t1 -> t2) ->(f(g t1) -> f(g t2))
针对您的具体问题:
f = undefined :: (x -> y -> w -> z -> a) ->g x ->yf2 .f₁ = f₁ >>>f ::(x -> y -> w -> z -> a) ->((->) (g x) (g y ))((->) x2 ((->) y2 (w2 -> z2 -> a2))) ->(g2 x2 -> g2 y2)---------------------------------------------------------------------------------------x2 ~ g x g ~ ((->) y2) y ~ (w2 -> z2 -> a2)---------------------------------------------------------------------------------------(x -> y -> w -> z -> a) ->(g2 x2 -> g2 y2) ~(x -> y -> w -> z -> a) ->(g2 (g x) -> g2 y2) ~(x -> (w2 -> z2 -> a2) -> w -> z -> a) ->( g2 (y2 -> x) -> g2 y2)
这是你从 GHCi 得到的,直到重命名变量.
I am new to Haskell.I am trying to understand how composition of types work.
(.) :: (b -> c) -> (a -> b) -> a -> c
fmap :: Functor f => (x -> y) -> f x -> f y
fmap . fmap :: (Functor f1, Functor f2) => (x -> y) -> f1 (f2 x) -> f1 (f2 y)
How I understood the above type information is as below.
1. (x -> y) -> f1 x -> f1 y -- First fmap
-> (x' -> y') -> f2 x' -> f2 y' -- Second fmap
2. Compare the (1) with (.) type signature then we get
In (b -> c)
b = (x -> y)
c = f1 x -> f1 y
In (a -> b)
a = (x' -> y')
b = f2 x' -> f2 y'
3. Now the result is a -> c but before that b in (b -> c) should be b in (a -> b)
(x -> y) === f2 x' -> f2 y'
That means x = f2 x' & y = f2 y'
4. Result is a -> c
(x' -> y') -> f1 x -> f1 y
Substituting (3) results here
(x' -> y') -> f1 (f2 x') -> f1 (f2 y')
This is Alpha equivalent to (x -> y) -> f1 (f2 x) -> f1 (f2 y)
To test my understanding I tried with various data types and I am success in few.Below is the type signature I can't figure out.
f = undefined :: (x -> y -> w -> z -> a) -> g x -> g y
-- Type of f . f in prelude
f . f :: (x -> (w1 -> z1 -> a1) -> w2 -> z2 -> a2) -> g (y -> x) -> g y
My approach to the above one
1. (x -> y -> w -> z -> a) -> g x -> g y
-> (x' -> y' -> w' -> z' -> a') -> g' x' -> g' y'
2. Comparing with (.) then
In (b -> c)
b = (x -> y -> w -> z -> a)
c = g x -> g y
In (a -> b)
a = (x' -> y' -> w' -> z' -> a')
b = g' x' -> g' y'
3. Comparing b from (b -> c) & (a -> b)
(x -> y -> w -> z -> a) === g' x' -> g' y'
That means x = g' x' & y -> w -> z -> a = g' y'
4. Result is a -> c
(x' -> y' -> w' -> z' -> a') -> g x -> g y
Now there is no direct y I can substitute in g y
My approach of seeing the composition is not working out for me.
Type derivation is a purely mechanical process.
(.) :: (b -> c ) -> (a -> b ) ->
(a -> c)
fmap₂ :: Functor f => (t3 -> t4) -> (f t3 -> f t4)
fmap₁ :: Functor g => ((t1 -> t2) -> (g t1 -> g t2))
-------------------------------------------------------------------------------------------
a ~ (t1 -> t2) b ~ (g t1 -> g t2)
b ~ (t3 -> t4) c ~ (f t3 -> f t4) b ~ (t3 -> t4 )
-------------------------------------------------------------------------------------------
fmap₂ . fmap₁ :: (Functor f, Functor g)
=> a -> c
~ (t1 -> t2) -> (f t3 -> f t4 )
~ (t1 -> t2) -> (f (g t1) -> f (g t2))
This is much nicer with (.)
's cousin, (>>>) fmap₁ fmap₂ = fmap₂ . fmap₁
:
(>>>) :: (a -> b ) ->
( b -> c ) ->
(a -> c )
fmap₁ :: Functor g => (t1 -> t2) -> (g t1 -> g t2)
fmap₂ :: Functor f => (t3 -> t4 ) -> (f t3 -> f t4)
------------------------------------------------------------------------------
a ~ (t1 -> t2) b ~ (g t1 -> g t2)
b ~ (t3 -> t4 ) c ~ (f t3 -> f t4)
------------------------------------------------------------------------------
fmap₁ >>> fmap₂ :: (Functor f, Functor g)
=> a -> c
~ (t1 -> t2) -> (f t3 -> f t4 )
~ (t1 -> t2) -> (f (g t1) -> f (g t2))
To your specific problem:
f = undefined :: (x -> y -> w -> z -> a) -> g x -> g y
f₂ . f₁ = f₁ >>> f₂ ::
(x -> y -> w -> z -> a) -> ((->) (g x) (g y ))
((->) x2 ((->) y2 (w2 -> z2 -> a2))) -> (g2 x2 -> g2 y2)
---------------------------------------------------------------------------------------
x2 ~ g x g ~ ((->) y2) y ~ (w2 -> z2 -> a2)
---------------------------------------------------------------------------------------
(x -> y -> w -> z -> a) -> ( g2 x2 -> g2 y2) ~
(x -> y -> w -> z -> a) -> ( g2 (g x) -> g2 y2) ~
(x -> (w2 -> z2 -> a2) -> w -> z -> a) -> ( g2 (y2 -> x) -> g2 y2)
which is what you got from GHCi, up to the renaming of variables.
这篇关于如何在 Haskell 中导出组合类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!