【问题标题】:isPalindrome function in Haskell gives an errorHaskell 中的 isPalindrome 函数给出错误
【发布时间】:2019-10-06 19:10:38
【问题描述】:

我正在尝试编写一个程序来检查列表是否为回文并返回 Bool。

isPalindrome :: [a] -> Bool
isPalindrome [] = True
isPalindrome [x] = True
isPalindrome xs | (head xs) == (last xs) = isPalindrome (init(tail xs))
                | otherwise = False

我收到这样的错误消息:

problem6.hs:4:19: error:
    * No instance for (Eq a) arising from a use of `=='
      Possible fix:
        add (Eq a) to the context of
          the type signature for:
            isPalindrome :: forall a. [a] -> Bool
    * In the expression: (head xs) == (last xs)
      In a stmt of a pattern guard for
                     an equation for `isPalindrome':
        (head xs) == (last xs)
      In an equation for `isPalindrome':
          isPalindrome xs
            | (head xs) == (last xs) = isPalindrome (init (tail xs))
            | otherwise = False
  |
4 | isPalindrome xs | (head xs) == (last xs) = isPalindrome (init(tail xs))
  |                   ^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.

因为我不是很有经验,所以我从错误消息中看不懂。所以我看不出我的代码中的错误在哪里。感谢您的帮助。

【问题讨论】:

    标签: haskell palindrome


    【解决方案1】:

    问题是你需要约束多态类型a。现在,编译器没有关于类型的信息,所以它甚至不知道(==) 是否为a 定义(这是No instance for (Eq a) arising from a use of ``==' 的来源。它试图推断@987654325 的实例@ 为a,但它不能。你需要帮助它。

    你应该输入类型:

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

    现在你告诉它,isPalindrome 只能得到作为 Eq 实例的事物列表。

    它指出这篇文章是因为您试图比较两个 a 的相等性:

    (head xs) == (last xs)
    

    关于错误信息的一点点:

     Possible fix:
        add (Eq a) to the context of
          the type signature for:
            isPalindrome :: forall a. [a] -> Bool
    

    在我的建议中=> 之前的东西称为上下文,您可以在其中为您的类型添加约束。这里的建议是告诉你完全按照我上面所说的去做(尽管以更冗长的方式)。

    【讨论】:

    • 那么,你的意思是当我不写 (Eq a) => 编译器对 a 的 typeclass 没有任何假设?
    • 正确。它只知道有一段时间a,它对类型一无所知。你需要告诉它什么是安全的假设。这样它就可以在调用站点强制执行所需的实例。
    • @Piamoon 如果您省略了类型签名,GHC 会推断出正确的类型,并带有约束。但是用户提供的签名优先,它不同意(说没有Eq 约束)与推断类型(说必须有Eq 约束)。无法按照你的命令,编译器出错了。它假设用户知道他们在做什么来提供该签名。
    【解决方案2】:
    import Data.List
    
    isPalindrome :: (Eq a) => [a] -> Bool
    isPalindrome [] = True
    isPalindrome [x] = True
    isPalindrome xs    
                    | (head xs /= head (reverse xs)) = False
                    | otherwise = isPalindrome ( tail (init xs) )
    

    【讨论】:

      猜你喜欢
      • 2018-04-14
      • 2021-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-03
      相关资源
      最近更新 更多