简体   繁体   English

Haskell:中缀(`:`)运算符是否有左侧标识?

[英]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 : xsx : xsxs (在同一范围内)必须是不同的列表,因为它们是不同的术语。

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: 例如,无论xxs是什么,这两个表达式都保证为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM