Function 用于Haskell id函数
Haskell中的哪些用途?它作为(以函数为参数的函数)的参数很有用,您希望某些特定值保持不变 示例1:如果某个值在Just中,则不使用该值,否则返回默认值7Function 用于Haskell id函数,function,haskell,functional-programming,Function,Haskell,Functional Programming,Haskell中的哪些用途?它作为(以函数为参数的函数)的参数很有用,您希望某些特定值保持不变 示例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
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
我们使用id
作为基本情况,通过将函数列表与(.)
折叠在一起,构建了一个新函数f
示例3:函数作为幺半群的基本情况(简化)
与我们的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
Data.HashTable>h插入h 7 2
Data.HashTable>Data.HashTable.lookup h7
只有两个
哈希表需要一个哈希函数。但是如果你的密钥已经被散列了呢?然后以零性能开销传递id函数作为哈希方法填充。在函数式语言中,函数是第一类值 可以作为参数传递的。 因此,
id
最常见的用法之一出现在
将函数作为
参数设置为另一个函数,以告诉它要执行的操作。
做什么的选择之一可能是
“别管它”——在这种情况下,您传递id
作为参数。对于不同类型的答案: 在通过合成链接多个函数时,我经常这样做:
foo = id
. bar
. baz
. etc
结束
它使事情更容易编辑。可以对其他“零”元素执行类似的操作,例如
foo = return
>>= bar
>>= baz
foos = []
++ bars
++ bazs
如果你操纵数字,特别是加法和乘法,你会注意到0和1的用处。同样,如果你操作列表,空列表也会非常方便。类似地,如果你操作函数(在函数式编程中非常常见),你会注意到
id
同样的有用性,假设你正在寻找一个谜题的某种解决方案,在这个谜题中,你每次都会移动。你从一个候选职位开始。在每个阶段,都有一个可能的转换列表,您可以对pos
(例如,在拼图中滑动一块)。在函数式语言中,将转换表示为函数是很自然的,因此现在可以使用函数列表创建移动列表。如果“什么也不做”是这个谜题中的合法动作,那么您可以用id
来表示。如果你没有这样做,那么你就需要把“什么都不做”作为一种特殊情况来处理,它的工作原理与“做某事”不同。通过使用id
可以在单个列表中统一处理所有情况
这可能就是为什么几乎所有的
id
用法都存在的原因。将“无所事事”与“有所作为”统一处理。当您需要在某个地方有一个函数,但希望做的不仅仅是保持它的位置(以“未定义”为例)
正如Stewart博士(即将)提到的,当您需要将一个函数作为参数传递给另一个函数时,它也很有用:
join = (>>= id)
let f = id in f 10
或作为功能的结果:
join = (>>= id)
let f = id in f 10
(您可能会在稍后编辑上述函数,以执行更“有趣”的操作……)
正如其他人所提到的,
id
是一个很好的占位符,当你需要某个功能时。我还可以帮助你提高高尔夫成绩。而不是使用
($)
您可以使用id保存单个字符
e、 g
zipWith id[(+1),succ][2,3,4]
这是一个有趣且非常有用的结果。因为我们发现了
id
的良好应用。这里有一个回文:)
导入控件。应用程序
pal::[a]->[a]
pal=(++)id反向
想象你是一台计算机,也就是说,你可以执行一系列步骤。那么,如果我想让你保持目前的状态,但我总是要给你一个指示(我不能只是沉默,让时间过去),我该给你什么指示?Id是为此创建的函数,用于返回未更改的参数(在前一台计算机中,参数将是其状态)并为其命名。只有当您拥有高阶函数时,当您使用函数而不考虑其中的内容时,这种必要性才会出现,这迫使您象征性地表示“不做任何事情”的实现。类似地,0被视为某物的数量,是没有数量的符号。实际上在代数中,0和id都被认为是+和运算的中性元素∘ (功能组成)分别或更正式地:
对于类型编号的所有x:
- 0+x=x
- x+0=x
join = (>>= id)
let f = id in f 10
- 身份证∘ f=f
- f∘ id=f
foldl'(.)id
优于foldr(.)id
?在这种情况下不是这样。严格性不会对函数的组合产生任何影响。@不要Stewart,我希望编译器对某些函数(如(+)
和其他需要绑定两个参数的外部函数)犯了严重错误例如更改应用程序树以折叠某些节点并释放它们使用的内存。另一个与此相关的示例是使用id
作为连续传递样式(CPS)中的基函数。我最喜欢的一个:numberOfTrues::[Bool]->Int;numberOfTrues=长度。过滤器id
很聪明,但你真的用真实的代码来实现吗?这几乎让我渴望Java。如果组合不能整齐地放在一行中,我会在真实代码中这样做。这通常发生在函数名很长和/或有许多有意义的参数时。在qwerty键盘上键入($)也是一件痛苦的事情,因此我非常喜欢在任何可能的地方使用id。如果空格算数,它就不会