[英]Haskell: Is there a left-side identity for the infix (`:`) operator?
In other words, what syntax (if any) could I use in place of XXX
in the following implementation of filter: 换句话说,在以下过滤器实现中,我可以使用什么语法(如果有的话)代替
XXX
:
filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' f (x:xs) =
let n = if f x then x else XXX
in n:(filter' f xs)
I'm aware of the following alternative implementation (which is recursive and only prepends) but would still be curious if the infix operator has a LHS identity. 我知道以下替代实现(它是递归的,只是prepends)但如果中缀运算符具有LHS身份,仍然会很奇怪。
filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' f (x:xs)
| f x = x:(filter' f xs)
| otherwise = filter' f xs
There is none. 空无一人。 This can be seen because
这可以看出因为
ghci> length (undefined : [])
1
so no matter what element you put there, you will always get a length of 1. 所以不管你放在哪个元素,你总会得到1的长度。
How about this phrasing: 这句话怎么样:
filter' f (x:xs) =
let n = if f x then (x:) else id
in n (filter' f xs)
Handwave alert: the following is strictly speaking a lie (because of undefined
and such), but it's still a useful idea. 手波警报:以下严格来说是谎言(因为
undefined
等),但它仍然是一个有用的想法。
One key property of types defined with Haskell data
declarations is that they are free : the set of values for a data
type is isomorphic to the set of normal-form terms (fully evaluated expressions) of that type. 使用Haskell
data
声明定义的类型的一个关键属性是它们是空闲的 : data
类型的值集与该类型的正常形式术语集 (完全计算的表达式)是同构的。 If two terms of the type are different, then they have different values. 如果该类型的两个术语不同,则它们具有不同的值。
From this it follows that x : xs
and xs
(in the same scope) must be different lists, simply because they are different terms. x : xs
, x : xs
和xs
(在同一范围内)必须是不同的列表,因为它们是不同的术语。
Put a bit differently, the semantics of data
types is that if you pattern match on a constructor application you always get back the same constructor and its arguments. 换句话说,
data
类型的语义是,如果在构造函数应用程序上进行模式匹配,则总是会返回相同的构造函数及其参数。 For example, these two expressions are guaranteed to be True
, no matter what x
and xs
may be: 例如,无论
x
和xs
是什么,这两个表达式都保证为True
:
case [] of
[] -> True
x:xs -> False
case (x:xs) of
[] -> False
x':xs' -> x == x' && xs == xs'
The left identity value you're looking for would be a counterexample to the second expression here. 您正在寻找的左侧身份值将是此处第二个表达式的反例。 Ergo, no such value exists.
因此,没有这样的价值。
There is none, but ++
does have an identity, namely []
. 没有,但
++
确实有一个身份,即[]
。 So this would work as well: 所以这也会起作用:
filter' _ [] = []
filter' f (x:xs) =
let n = if f x then [x] else []
in n ++ (filter' f xs)
This is the same as @luqui's answer (as you could prove) only less efficient , but it keeps things a bit lower-order. 这与@ luqui的答案(正如你可以证明的那样)效率相同,但效率却低一些。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.