2011-10-21 16 views
2

文字列を分割して渡される文字の前にある部分文字列を返すが、私たちはちょうどハスケルを開始しており、それは私にとっては中国語のようだ。私はそれをつぶってきましたが、運はありません。私はハスケルの部分文字列

--spanString returns substring of string s before char c 
spanString (c, [s])::(c, [s]) -> [] 
spanString (c, a:b) = 
    let (x, y) = spanString (c, b) 
    in 
     if a < c then (a:x,y) 
     else (x, a:y) 

をめちゃくちゃにしています何: は、ここで私がこれまで持っている何ですか?

答えて

3

Err、かなり。

まず、型宣言が間違っています。 Haskellは型に大文字の名前を使用し、ほとんどの言語と同様に大括弧でパラメータを渡しません。私たちは、あなたがおそらくspanStringのあなたの定義は構文的に右、まだ間違っている

spanString :: Char -> String -> String 

のような何かをしたいの代わりに

y = sin (x) 

y = sin x 

を書きます。最初の文字が一致しない場合は、文字列の残りの部分をspanStringし、最初の文字を先頭に付けて結果を返したいと考えています。最初の文字が一致した場合は、 ""を返します。

+0

引数の型がタプルであっても?なぜなら、charとlistを持つタプルを渡すはずだからです。 – Mike

+0

@Mike:その場合は問題ありません。 'spanString ::(Char、String) - > String'がありますが、それはむしろハスケルではありません。 – ivanm

4

まず、あなたのタイプシグネチャは完全に台無しです。それは存在しないか、またはspanString :: <some type>の形式でなければなりません。もし我々が二重コロンの前に立っている(c, [s])を無視しても、残りはまだ変わったものです。これは、「(c, [s])の値を任意のcおよびsのタイプ[]の値に変換する関数」(cおよびsは型変数)として読み取ることができます。まず、Haskellにタイプ[]はありません。要素タイプのないリストタイプはありません。次に、csで作業することはできません。我々はそれらを比較することができなければなりません、そうですか?

実際には多型を使用しないようにして、必要なタイプを正確に指定しましょう。何らかの理由でタプルに詰め込まれた文字と文字のリストが必要です:(Char, [Char])Charは大文字で始まります。つまり、型変数ではなく、具体的な型です。結果のタイプはどうですか?問題の説明を信頼する場合は、文字リスト([Char])を返す必要がありますが、コードを見ると明らかにリストのタプル(([Char], [Char]))が返されます。さて、2番目のリストが役に立つかもしれませんが、今のままにしましょう:

spanString :: (Char, [Char]) -> ([Char], [Char])` 

コードがコンパイルされました。

ただし、実行すると、例外:Non-exhaustive patterns in function spanStringが発生してクラッシュします。これは、渡されたリストが空の場合には処理しないためです。あなたがそれを行う場合は、

spanString (_, []) = ([], []) 

のような式を追加することによって、あなたの機能がうまく動作しますが、今のは、それが何をするかを見てみましょう。リスト分割のための関数があることがわかります:タプルの最初の要素としてcより小さい指定された文字列のすべての文字を返し、2番目の要素として他のすべての文字を返します。バグのようです(あなたは全く異なる機能を実装しました!)。

+0

ええ、2番目に返されたリストは私のせいでした。私は最初にこれを書きましたが、何かを試してみたいと思っていましたが、返されたリストが1つだけあるはずです。私はまったく間違ったやり方でこのことをやっているようで、ここからどこに行くのか分からない。 – Mike

2

タイプ定義が間違っています。

spanString :: Char-> String-> String 
    spanString _ [] = [] 
    spanString c (x:xs) | c==x = [] 
         | otherwise = x:spanString c xs 
+1

あなたの答えは正しいですが、質問は宿題としてマークされ、宿題については、タグの説明で説明されているように、「完全なものを表示するのではなく、回答。" – HaskellElephant

+0

これは私が持っていた問題に完全には答えませんが、助けになりました。受け入れられた答えとそれに関するコメントは、本当にそれを得るために私を得たものです。 – Mike

0

このようなユーティリティ機能は、ほとんどの場合、Preludeまたは標準ライブラリの1つにあります。この場合、takeWhileは役立ちます:

spanString :: (Char, String) -> String 
spanString (c, s) = takeWhile (/= c) s 

(彼らはcを等しくいない間、すなわち、文字を取っておきます)。

タプルの引数を渡すのはやや奇妙ですが、それが必要な場合はそうです。