Haskell中id function的用途是什么?
答案 0 :(得分:80)
它作为higher order functions的参数(将函数作为参数的函数)很有用,你希望某些特定值保持不变。
示例1 :如果是Just,则保留一个值,否则返回默认值7.
Prelude Data.Maybe> :t maybe
maybe :: b -> (a -> b) -> Maybe a -> b
Prelude Data.Maybe> maybe 7 id (Just 2)
2
示例2 :通过折叠构建功能:
Prelude Data.Maybe> :t foldr (.) id [(+2), (*7)]
:: (Num a) => a -> a
Prelude Data.Maybe> let f = foldr (.) id [(+2), (*7)]
Prelude Data.Maybe> f 7
51
我们使用f
作为基本案例,将功能列表与(.)
一起折叠,从而构建了一个新功能id
。
示例3 :函数为monoids的基本情况(简化)。
instance Monoid (a -> a) where
mempty = id
f `mappend` g = (f . g)
与我们使用fold的示例类似,可以将函数视为可连接值,id
用于空案例,(.)
用作追加。
示例4 :一个简单的哈希函数。
Data.HashTable> h <- new (==) id :: IO (HashTable Data.Int.Int32 Int)
Data.HashTable> insert h 7 2
Data.HashTable> Data.HashTable.lookup h 7
Just 2
哈希表需要哈希函数。但是,如果你的密钥已经散列怎么办?然后传递id函数,以填充哈希方法,没有性能开销。
答案 1 :(得分:69)
如果你操纵数字,特别是加法和乘法,你会注意到0和1的有用性。同样,如果你操纵列表,那么空列表就会变得非常方便。类似地,如果你操作函数(在函数式编程中很常见),你会发现id
的相同用途。
答案 2 :(得分:20)
在函数式语言中,函数是第一类值
你可以作为参数传递。
因此,id
的最常见用途之一就出现了
你传递一个函数
参数到另一个函数告诉它该怎么做。
可能的选择之一是做什么
“只是不管它” - 在这种情况下,你通过id
作为参数。
答案 3 :(得分:6)
假设您正在寻找某种解决方案,您可以在每个回合中进行移动。您从候选职位pos
开始。在每个阶段都有一个可以对pos
进行转换的列表(例如,在拼图中滑动一块)。在函数式语言中,将转换表示为函数是很自然的,所以现在可以使用函数列表创建移动列表。如果“无所事事”是这个难题的合法举措,那么你可以用id
表示。如果你没有这样做,那么你需要处理“无所事事”作为一个与“做某事”不同的特殊情况。通过使用id
,您可以在一个列表中统一处理所有案例。
这可能就是为什么几乎所有id
的使用都存在的原因。用“做某事”统一处理“无所事事”。
答案 4 :(得分:3)
对于另一种答案:
当通过合成链接多个函数时,我经常这样做:
foo = id
. bar
. baz
. etc
结束
foo = bar
. baz
. etc
它使编辑更容易。人们可以用其他“零”元素做类似的事情,比如
foo = return
>>= bar
>>= baz
foos = []
++ bars
++ bazs
答案 5 :(得分:3)
我还可以帮助提高您的高尔夫分数。而不是使用
($)
您可以使用ID保存单个字符。
e.g。
zipWith id [(+1), succ] [2,3,4]
一个有趣的,非常有用的结果。
答案 6 :(得分:3)
因为我们找到了id
的好应用程序。在这里,有一个回文:)
import Control.Applicative
pal :: [a] -> [a]
pal = (++) <$> id <*> reverse
答案 7 :(得分:3)
想象一下你是一台计算机,即你可以执行一系列步骤。然后,如果我希望你保持现状,但我总是要给你一个指令(我不能只是静音,让时间过去),我会给你什么指示? Id是为此创建的函数,用于返回参数不变(在前一个计算机的情况下,参数将是其状态)以及具有其名称。这种必要性只有在您具有高阶函数时才会出现,当您使用函数进行操作而不考虑其中的内容时,这会强制您象征性地表示甚至不执行任何操作&#34;实现。类似地被视为一定数量的东西,是缺少数量的象征。实际上在代数中,0和id分别被认为是操作+和function(函数组合)的中性元素,或者更正式:
表示所有类型x的x:
表示所有类型的函数:
答案 8 :(得分:0)
每当你需要在某个地方拥有一个函数,但想要做的不仅仅是保持它的位置(以'undefined'为例)。
这也很有用,正如(很快将要)Stewart博士所提到的那样,当你需要将函数作为参数传递给另一个函数时:
join = (>>= id)
或作为函数的结果:
let f = id in f 10
(大概你以后会编辑上面的函数来做一些更“有趣”的事情......;)
正如其他人所提到的,id
是一个很棒的占位符,可以在某个地方使用某个功能。