Haskell 两个函数的组合类型是什么?例如(flip.const)
我已经开始学习Haskell,我很好奇如何找到函数的组合类型:例如:Haskell 两个函数的组合类型是什么?例如(flip.const),haskell,types,type-inference,ghci,strong-typing,Haskell,Types,Type Inference,Ghci,Strong Typing,我已经开始学习Haskell,我很好奇如何找到函数的组合类型:例如: :t flip flip :: (a -> b -> c) -> b -> a -> c :t const const :: a -> b -> a 如何手动执行:t(flip.const) 当然,GHCi可以帮助您: :t (flip.const) (flip . const) :: (b -> c) -> b -> a -> c 但是你自己怎么做呢?这
:t flip
flip :: (a -> b -> c) -> b -> a -> c
:t const
const :: a -> b -> a
如何手动执行:t(flip.const)
当然,GHCi可以帮助您:
:t (flip.const)
(flip . const) :: (b -> c) -> b -> a -> c
但是你自己怎么做呢?这里有三个功能:
(.)
函数用作运算符,则实际上已编写:
(.) flip const
或者更详细:
((.) flip) const
现在,让我们首先以详细的方式编写函数的签名,并使用不同的可变名称,以便这些签名不会冲突:
(.) :: (b -> c) -> ((a -> b) -> (a -> c))
flip :: (d -> (e -> f)) -> (e -> (d -> f))
const :: g -> (h -> g)
因此,我们将()
应用于flip
,这意味着我们必须将类型为(b->c)
的()
的参数与flip的签名相匹配,因此我们通过以下方式解决此问题:
b -> c
(d -> (e -> f)) -> (e -> (d -> f))
这是唯一可能的匹配(请注意括号)。这意味着:
b ~ (d -> (e -> f))
c ~ (e -> (d -> f))
(此处a~b
表示a
和b
是同一类型)
因此,(.)flip
的类型为
(.) flip :: (a -> b) -> (a -> c)
这也是一个带有一个参数的函数(Haskell中的所有函数都有一个参数),该参数的类型为a->b
。
我们将该函数应用于常量
,因此我们再次进行模式匹配:
a -> b
g -> (h -> g)
这意味着a~g
和b~(d->(e->f))~(h->g
,因此我们知道d~h
和g~(e->f)
我们知道(.)flip)const
的类型为:
((.) flip) const :: a -> c`
所以现在是用a
代替g
和g~(e->f)
,所以a~(e->f)
。此外,我们知道c~(e->(d->f))
,这意味着类型为:
((.) flip) const :: (e -> f) -> (e -> (d -> f))
或者以不太详细的形式:
flip . const :: (e -> f) -> e -> d -> f
除了变量重命名外,它与GHCi派生的类型相同。这里有三个功能:
(.)
函数用作运算符,则实际上已编写:
(.) flip const
或者更详细:
((.) flip) const
现在,让我们首先以详细的方式编写函数的签名,并使用不同的可变名称,以便这些签名不会冲突:
(.) :: (b -> c) -> ((a -> b) -> (a -> c))
flip :: (d -> (e -> f)) -> (e -> (d -> f))
const :: g -> (h -> g)
因此,我们将()
应用于flip
,这意味着我们必须将类型为(b->c)
的()
的参数与flip的签名相匹配,因此我们通过以下方式解决此问题:
b -> c
(d -> (e -> f)) -> (e -> (d -> f))
这是唯一可能的匹配(请注意括号)。这意味着:
b ~ (d -> (e -> f))
c ~ (e -> (d -> f))
(此处a~b
表示a
和b
是同一类型)
因此,(.)flip
的类型为
(.) flip :: (a -> b) -> (a -> c)
这也是一个带有一个参数的函数(Haskell中的所有函数都有一个参数),该参数的类型为a->b
。
我们将该函数应用于常量
,因此我们再次进行模式匹配:
a -> b
g -> (h -> g)
这意味着a~g
和b~(d->(e->f))~(h->g
,因此我们知道d~h
和g~(e->f)
我们知道(.)flip)const
的类型为:
((.) flip) const :: a -> c`
所以现在是用a
代替g
和g~(e->f)
,所以a~(e->f)
。此外,我们知道c~(e->(d->f))
,这意味着类型为:
((.) flip) const :: (e -> f) -> (e -> (d -> f))
或者以不太详细的形式:
flip . const :: (e -> f) -> e -> d -> f
除了变量重命名外,它与GHCi派生的类型相同。我们还有(>>>)=flip(.)
,这更容易处理,按类型:
f . g = g >>> f
g :: a -> b
f :: b -> c
g >>> f :: a -> c
因此
或翻转。常数::(b->c)->b->a->c
。GHCi也这么说
从这种类型中,我们立即看到(flip.const)fxz=fx
。实际上(flip.const)fxz=flip(constf)xz=constfzx=fx
要从中吸取三个教训:
- 类型关联到右边,而函数应用程序关联到左边,
,fxyz=(((fx)y)z)
李>f::a->(b->(c->d))
- 垂直对齐的东西有帮助李>
- 在不同类型中对类型变量进行编号有助于将它们分开
(>>>)=flip(.)
,更容易处理,按类型:
f . g = g >>> f
g :: a -> b
f :: b -> c
g >>> f :: a -> c
因此
或翻转。常数::(b->c)->b->a->c
。GHCi也这么说
从这种类型中,我们立即看到(flip.const)fxz=fx
。实际上(flip.const)fxz=flip(constf)xz=constfzx=fx
要从中吸取三个教训:
- 类型关联到右边,而函数应用程序关联到左边,
,fxyz=(((fx)y)z)
李>f::a->(b->(c->d))
- 垂直对齐的东西有帮助李>
- 在不同类型中对类型变量进行编号有助于将它们分开