我已经编写了下面的代码来测试列表是否是Palindrome。令我惊讶的是它没有编译错误“没有因使用== ....而导致的(Eq a)实例”。我的假设是编译器不知道leftHalf
和rightHalf
是列表。
isPalindrome :: [a] -> Bool
isPalindrome [] = False
isPalindrome xs = if (leftHalf == reverse rightHalf)
then True
else False
where leftHalf = take center xs
rightHalf = drop center xs
center = if even (length xs)
then (length xs) `div` 2
else ((length xs) - 1) `div` 2
1)如何告诉编译器leftHalf
和rightHalf
是列表?
2)我如何使用模式匹配或其他haskell语言功能来解决这个问题?
编辑:谢谢大家的意见。特别提到Matt Fenwick的文档链接和Duri的优雅提示。我将在下面写下最终解决方案以防万一
isPalindrome' :: (Eq a) => [a] -> Bool
isPalindrome' [] = False
isPalindrome' xs = if p then True else False
where p = leftHalf == rightHalf
leftHalf = take c xs
rightHalf = take c (reverse xs)
c = div l 2
l = length xs
isPalindrome'
可以像Demi指出的那样得到改善
isPalindrome'' :: (Eq a) => [a] -> Bool
isPalindrome'' [] = False
isPalindrome'' xs = if (reverse xs) == xs then True else False
答案 0 :(得分:4)
为了测试两个列表是否相等,必须可以测试列表中的项是否相等。因此,您的[a]
类型列表必须确保a
是Eq
的实例。
另外,作为一种风格问题:
x = if c then True else False
可以替换为
x = c
答案 1 :(得分:2)
查看Eq
类型类:
ghci> :i (==)
class Eq a where
(==) :: a -> a -> Bool
...
-- Defined in GHC.Classes
infix 4 ==
isPalindrome
上a type constraint需要{。}}。
此外,此代码
if (leftHalf == reverse rightHalf)
then True
else False
不必要地长。
答案 2 :(得分:1)
您应该将类型更改为:
isPalindrome :: Eq a => [a] -> Bool
找到中心真的无关紧要,只需写xs == reverse xs
就可以了 - 当你计算length xs
时,你会查看所有列表并且没有经济效果。