2012-03-21 12 views
8

だから私はHaskellのHaskellの最初、真ん中の部分をパターンマッチング、そして最後

swapReverse :: String => String 
swapReverse [x] = [x] 
swapReverse [x,y] = [y,x] 
swapReverse (x:xs:l) =   -- pattern match fails here 
    let last = [l] 
     middle = xs 
     first = [x] 
    in last ++ swapReverse middle ++ first 

に単純な文字列の逆機能をやってみたかったのでfirstlastを持っているHaskellでパターン構造を定義する方法があります要素、およびmiddleのすべての要素

+2

型宣言に注意してください:) おそらく 'swapReverse :: String - > String'を意味します。あるいは、おそらく' swapReverse :: [a] - > [a] 'のようなもっと一般的なものです。 –

+0

ところで、リンクされたリストの最後の要素を見つけることはO(N)です。あなたは実際にそれをやりたいとは決してほとんど決してありません。 – hugomg

+0

タイプシグネチャは 'String - > String'でなければなりません。BTW – Landei

答えて

6

いいえ、できません。どうして?パターンは値とそのサブパーツに一致しますが、リストの「中間」はリストのサブパーツではないためです。リスト[1, 2, 3, 4]は、その構造上、1:(2:(3:(4:[])))です。したがって、first1last4に一致させたいとします。どちらもリストの下位部分であり、失格にはなりません。しかしmiddleは、リストのサブパートではない2:(3:[])であり、一致することはできません。

リストの最初と最後の要素を同時に一致させるパターンを書くことはできません。パターンはコンパイル時に固定された深さを持っています。

5

パターン・マッチングはコンストラクタで動作し、:あなたは、リストの途中で一致することはできませんので、はリストのコンストラクタです。あなたは新しいリストを後方に構築する必要があります(明らかに:))これは、頭部を取り、それをリストの残りの部分の逆に追加することによって行うことができます。

+2

'(x:xs:l) 'は実際には一致しますが、 'x'と最初の要素、' xs'と二番目の要素、 'l'とリストの残りの部分をマッチさせます。 –

1

このコードを試してみてください。

last1 (x:xs:l) = (x,xs,l) 

lあなたのリストの最後の要素を取得していない、それはで最初の2つの要素が割り当てられている最初の2つの変数のほかにあなたのリストの残りの部分をだ取得リスト。

リストにパターンマッチを書き込むと、最初の変数に最初の要素が割り当てられます。最後に残ったものがすべて割り当てられている最後の変数に到達するまで続きます。 xの後にsを追加することについて特別なものはありません。yという変数は同じことを行います。

リストの最後の要素を取得する場合は、(x:xs)に似たパターンを作成し、xsで再帰を使用し、最後の要素である1つのリスト要素まで取得するまでそのパターンを適用する必要があります。しかし、リストの最初と最後の要素を見つけることを含まないリストを逆転させるより良い方法は、Adam Bergmark'sの答えを読むことをお勧めします。

0

作業バージョン:この実装は、性能面の災害であること

swapReverse :: String -> String 
swapReverse (x:xs) = [last xs] ++ swapReverse (init xs) ++ [x] 
swapReverse xs = xs 

注意。フォールドおよび/またはアキュムレータを使用した実装ははるかに効率的です。

関連する問題