2011-09-06 23 views
5
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プログラマーで、なぜこのエラーが発生しているのか分かりません。何か助けてください。初心者haskellプログラマー

+0

この問題は解決しましたか? – MGwynne

答えて

13

xsはリストのように扱いますが、(x1:xs:x2:[])は入力リストの要素であることを前提としています。 (x1:xs:x2:[]) 3つの要素、及びx1xsx2のみリストに一致すること

注型aの要素であろう。

のでxsはタイプaのですが、あなたはisPalindromeにそれを渡すように、我々は、それが何かのリストでなければならないと仮定することができますので、型システムは、タイプ[a1]を呼び出します。

あなたが欲しいものをエンコードするための最も簡単な方法は次のとおりです。ここで

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

はあなたの試みに似た答えを、理解しやすいです:

isPalindrome [] = True 
isPalindrome [x] = True 
isPalindrome xs = (head xs == last xs) && isPalindrome (init (tail xs)) 

だから、空または1要素のリストがされます最初の要素と最後の要素が等しい場合には、回文(palindrome)であり、中間の要素は、回文(palindrome)である。

MGwynneの回答は、と多くのパフォーマンスがあり、すべての手順でリストをトラバースする必要があるため、です。

+0

+1質問に似た答えを出し、それを使用しない理由を説明してください! – MGwynne

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:[]) 

がちょうど3つの要素を持つリストと一致していることを、今は明らかです:あなたはこれらのコンストラクタに一致しているリスト上のパターンマッチングは、

あなたはx1、xs、x2という名前をつけています。

私は役立つことを願っています。