我正在尝试实现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而没有任何错误。我做错了什么?
答案 0 :(得分:4)
(lwords,words,x:xs)<-get
x:xs
匹配包含至少一个元素的列表(x
成为第一个元素,xs
成为列表的其余部分),因此当模式匹配失败时元组的第三个成员是[]
。
解决方案:替换
(lwords,words,x:xs)<-get
case x:xs of
与
(lwords,words,xs)<-get
case xs of
(并考虑在函数的后面使用不同的变量名称:如果有两个或多个具有相同名称的变量,它会变得混乱。)
编辑:如果您打开警告(将-Wall
标志传递给ghc / ghci),您将在编译时收到警告,表明该模式可能无法在运行时匹配。 (您还会收到一条警告:有一个xs
变量隐藏另一个xs
变量,称为阴影。)