0

Haskellの標準単語機能を実装しようとしています。State Monad を使用して問題を解決しています。

私のコードは:

type WorS = ([String],String,String)

words' :: State WorS [String]
words' = do
           (lwords, words, x:xs) <- get
           case x:xs of
           (' ':xs) -> (put (words:lwords, [], xs) >> words')
           ([]) -> return lwords
           (_:xs)-> (put (lwords, words ++ [x], xs) >> words')

run_word' ::  String ->[String]
run_word' x = reverse $ fst (runState words' ([], [], x))

私がする時:

run_word' "guns and roses"

次のエラーが表示されます。

Exception: Pattern match failure in do expression

コードはエラーなしで ghci にロードされています。私は何を間違っていますか?

4

1 に答える 1

4
       (lwords,words,x:xs)<-get

x:xsは、少なくとも 1 つの要素を持つリストに一致します (x最初の要素にxsなり、リストの残りになります)。そのため、タプルの 3 番目のメンバーが の場合、パターン マッチの失敗が発生し[]ます。

解決策:交換

       (lwords,words,x:xs)<-get
       case x:xs of

       (lwords,words,xs)<-get
       case xs of

(そして、関数の後半で別の変数名を使用することを検討してください。同じ名前の変数が 2 つ以上あると混乱します。)

編集:警告を有効にする (-Wallフラグを ghc/ghci に渡す) と、実行時にパターンが一致しない可能性があるという警告がコンパイル時に表示されます。xs(シャドウイングと呼ばれる、ある変数が別の変数を隠しているという警告も表示xsされます。)

于 2013-02-15T19:41:40.807 に答える