0

再会!

所以我想写一个函数是Haskell如下

remove_nulls :: [ ([String], Int) ] -> [ ([String], Int) ] -> [ ([String], Int) ]
remove_nulls listofpair (y:ys)
| null listofpair = (y:ys)
| null (fst(head listofpair))= remove_nulls (tail listofpair) (y:ys)
| otherwise = remove_nulls (tail listofpair) (y:(head listofpair):ys)

这需要一个可能看起来像这样的输入

remove_nulls [ ([],0) , (["abc", "dce"], 2) ] []

这个想法是,如果它的第一个值包含空值,它将从列表中删除元组。但是,每次我调用它时,它都会返回“函数 remove_nulls 中的非详尽模式”。

我试过改变基本情况,但我总是得到相同的结果。任何帮助和利用都会很棒(目前只是学习 Haskell)。

4

4 回答 4

6

如果您只想删除所有第一个字段为空的对,

removeNulls xs = filter (not . null . fst) xs

会这样做。如果您还不熟悉 中的符号(not . null . fst),这只是编写函数的一种更短的方法\pair -> not (null (fst pair))。有关更多解释,请参阅此 SO question 。

您的原始函数似乎尝试在第二个输入列表的第一个元素之后插入第一个列表中的好元素,并且无法工作,因为它不涵盖第二个列表为空的情况。

于 2013-11-05T08:20:50.713 回答
0

remove_nulls因此应该获取列表并返回一个新列表:

remove_nulls :: [ ([String], Int) ] -> [ ([String], Int) ]
remove_nulls lst = [(x,y) | (x,y) <- lst, (not.null) x]
于 2013-11-05T08:15:53.787 回答
0

您错过了添加一个额外条件:当第二个列表为空时

remove_nulls :: [([a], t)] -> [([a], t)] -> [([a], t)]
remove_nulls [] ys = ys
remove_nulls (([], _):xs) ys = remove_nulls xs ys
remove_nulls (x:xs) [] = remove_nulls xs [x]       -- new condition
remove_nulls (x:xs) (y:ys) = remove_nulls xs (y:x:ys)
于 2013-11-05T10:53:10.800 回答
0

因为您使用空列表作为第二个参数调用 remove_nulls,并且您仅提供了当第二个参数具有至少一个元素时的定义(这是(y:ys)第一行的模式),找不到匹配项,导致错误你看到的消息。

我认为(但没有尝试过)如果你摆脱了y:比赛,它应该编译(但也许还没有做你想做的事!)。所以尝试这样的事情:

remove_nulls :: [ ([String], Int) ] -> [ ([String], Int) ] -> [ ([String], Int) ]
remove_nulls listofpair ys
  | null listofpair = ys
  | null (fst (head listofpair))= remove_nulls (tail listofpair) ys
  | otherwise = remove_nulls (tail listofpair) (head listofpair:ys)
于 2013-11-05T09:03:27.203 回答