isPalindrome::(Eq a) => [a] -> Bool
isPalindrome [] = True
isPalindrome [x] = True
isPalindrome (x1:xs:x2:[])
| x1 == x2 = isPalindrome xs
|otherwise = False
[1 of 1] Compiling Main ( myHas.hs, interpreted )
myHas.hs:37:27:
Couldn't match expected type `[a]' against inferred type `a1'
`a1' is a rigid type variable bound by
the type signature for `isPalindrome' at myHas.hs:33:18
In the first argument of `isPalindrome', namely `xs'
In the expression: isPalindrome xs
In the definition of `isPalindrome':
isPalindrome (x1 : xs : x2 : [])
| x1 == x2 = isPalindrome xs
| otherwise = False
我是初学者haskell程序员,并且不知道为什么我会收到此错误,请帮忙吗?
答案 0 :(得分:13)
您将xs
视为列表,但(x1:xs:x2:[])
假定它是您输入列表的元素。
请注意,(x1:xs:x2:[])
仅匹配包含3个元素的列表,x1
,xs
和x2
将是a
类型的元素。
所以xs
的类型为a
,但是当您将其传递给isPalindrome
时,我们只能假设它必须是某个列表,因此类型系统调用类型{ {1}}。
编码所需内容的最简单方法是:
[a1]
答案 1 :(得分:7)
这是一个易于理解的答案,类似于您的尝试:
isPalindrome [] = True
isPalindrome [x] = True
isPalindrome xs = (head xs == last xs) && isPalindrome (init (tail xs))
所以空格或单元素列表是回文序列,如果第一个和最后一个元素相等,则较长列表是回文序列,而“中间”元素也是回文序列。
请注意,MGwynne的答案 更高效,因为上述解决方案必须在每个步骤中遍历列表。
答案 2 :(得分:5)
我觉得这里需要对列表使用的语法进行解释,到目前为止还没有给出。首先,Haskell中列表类型的定义是:
data [a] = a : [a] | []
其中表示列表为空([]
)或者是(:
)构造函数,其左侧参数为a
,另一个列表(定义中的[a]
。这意味着列表[1,2,3]
实际上是1 : (2 : (3 : []))
,但这也可以只写为1 : 2 : 3 : []
。
当列表上的模式匹配时,您将匹配这些构造函数:
f [] = … -- match the empty list
f (x:[]) = … -- match a list with one element, which you name x
f (x:xs) = … -- match the first element of the list, and whatever the rest of
-- the list is, but it must have at least one element. if you call
-- f [1,2,3], x will be bound to 1, and xs will be bound to [2,3]
-- because [1,2,3] is the same as (1:[2,3])
f (x:y:xs) = … -- matches a list with at least two elements, which you
-- call x and y respectively
f (xs:ys:zs:things) = … -- matches a list with at least three elements,
-- which you name, xs, ys and zs.
因此,希望现在很清楚
f (x1:xs:x2:[])
匹配具有三个元素的列表,您将其命名为x1,xs和x2。
我希望有所帮助。