Haskell 高阶函数与id
我似乎无法理解如何将Haskell 高阶函数与id,haskell,higher-order-functions,Haskell,Higher Order Functions,我似乎无法理解如何将id用作某些高阶函数的参数。我在某个地方读到过这样的话,它被用来“让某些东西单独呆着”,但我似乎无法理解它 例如,为什么是lifta2idf(b->c)->f b->f c的类型 还有,为什么我不能将id传递给g以获取 g :: (Int -> Int -> Int) -> Int -> Int -> Int ? 我在某个地方读到,[id]被用来“别管什么事”,但我似乎无法理解它 id用于“让某件事单独处理”,因为它只做了这些——也就是说,什么
id
用作某些高阶函数的参数。我在某个地方读到过这样的话,它被用来“让某些东西单独呆着”,但我似乎无法理解它
例如,为什么是lifta2id
f(b->c)->f b->f c
的类型
还有,为什么我不能将id
传递给g
以获取
g :: (Int -> Int -> Int) -> Int -> Int -> Int
?
我在某个地方读到,[id
]被用来“别管什么事”,但我似乎无法理解它
id
用于“让某件事单独处理”,因为它只做了这些——也就是说,什么都不做:
id :: x -> x
id x = x
因此,id
通常显示为传递给高阶函数的不做任何事情的占位符fmap id foo
实际上不会更改foo
中的值(事实上,fmap id=id
,这是第一个函子定律),id。f
和f。id
都等同于f
,依此类推。一个更有趣的例子是,id
用作使用foldr
构建函数的基本情况
例如,为什么是lifta2id
f(b->c)->f b->f c
的类型
liftA2
的类型为:
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
在liftA2 id
的情况下,我们有
(a -> (b -> c)) ~ (x -> x)
。。。所以
a ~ x
(b -> c) ~ x
。。。因此
liftA2 id :: f (b -> c) -> f b -> f c
(正如你可能知道的,liftA2 id=()
。如果你把它写成liftA2($)
,($):(a->b)->(a->b)
仅仅是一个专门的id
)
还有,为什么我不能将id
传递给g
以获取
g :: (Int -> Int -> Int) -> Int -> Int -> Int
因为那样你就必须统一
(Int -> (Int -> Int)) ~ (x -> x)
。。。这是不可能的,因为
x
不能同时是Int
和Int->Int
要直观地理解“您必须统一…”,请尝试此项id
可以不使用Int
而使用typeInt->Int
(这与g
的参数具有相同的参数类型);或者id
可以不使用Int->Int
函数,而使用type(Int->Int)->(Int->Int)
aka(Int->Int)->Int->Int
(这与g
的参数具有相同的结果类型)。但是,与人类不同的是,如果你试图单独留下两个Int
s,你不会从另一端只得到一个Int
,因此id
不能有类型Int->Int->Int
liftA2 id
是liftA2($)的模糊版本。实际上,当id
被视为二进制函数时,最好将其写成($)
。