如何使用列表理解和递归检测 Haskell 中两个相邻的相同字符?

How to detect two adjacent identical characters in Haskell using list comprehension and recursion?

我正在尝试编写一个函数 detadj :: String -> Bool,它接受一个字符串,如果 returns 为真 该字符串包含两个相同的相邻字符。例如:

detadj "" == False
detadj "s" == False
detadj "ss" == True
detadj "Misisipi" == False
detadj "Mississippi" == True
detadj "single-dash" == False
detadj "double--dash" == True

我有两个版本的函数,第一个在列表理解中,在很多情况下都是错误的,但最普遍的是 detadjlc ["ss"] 时,由于使用 (x:y:xs)位:

detadjlc :: String -> Bool
detadjlc [] = False
detadjlc [x] = False
detadjlc (x:y:xs) = head[ x == y && isAlpha x == isAlpha y | (x,y) <- zip (x:y:xs) xs ]

和递归(当输入类似于 detadjr [" ee"] 产生 False 而不是 True 时,这不起作用):

detadjr :: String -> Bool
detadjr [] = False
detadjr [x] = False
detadjr (x:y:xs) | x == y = True
           | otherwise = d xs

有哪些方法可以解决这些问题?

你的递归函数很好,除了一个小细节:你忘记将 y 放回递归调用的列表中。 (我假设 ddetadjr 的拼写错误。)仅仅因为 xy 不同并不意味着 y 和 [= 的第一个字符17=] 可能不一样。

detadjr :: String -> Bool
detadjr (x:y:xs) = (x == y) || detadjr (y:xs)
detadjr _ = False

(如果您首先检查 2 个或更多字符的字符串,那么单例和空列表可以折叠成一个基本案例。)

以下是使用列表理解的迭代解决方案。我们创建一个包含输入列表相邻元素的元组列表。然后我们比较元组中的那些元素。

detadjlc :: String -> Bool
detadjlc xs = or [x == y | (x, y) <- zip xs (tail xs)]

递归解决方案最好按照@chepner 已发布的方式完成。