家庭作业:在Haskell中将中间表达式与==进行比较

时间:2012-05-03 14:45:46

标签: haskell

我已经编写了下面的代码来测试列表是否是Palindrome。令我惊讶的是它没有编译错误“没有因使用== ....而导致的(Eq a)实例”。我的假设是编译器不知道leftHalfrightHalf是列表。

    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)如何告诉编译器leftHalfrightHalf是列表?
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

3 个答案:

答案 0 :(得分:4)

为了测试两个列表是否相等,必须可以测试列表中的项是否相等。因此,您的[a]类型列表必须确保aEq的实例。

另外,作为一种风格问题:

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 ==

isPalindromea type constraint需要{。}}。

此外,此代码

if (leftHalf == reverse rightHalf)
              then True
              else False

不必要地长。

答案 2 :(得分:1)

您应该将类​​型更改为:

isPalindrome :: Eq a => [a] -> Bool

找到中心真的无关紧要,只需写xs == reverse xs就可以了 - 当你计算length xs时,你会查看所有列表并且没有经济效果。