美好的一天!
所以我试着写一个函数是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) ] []
这个想法是,如果元组的第一个值包含null,它将从列表中删除元组。但是,每次调用它都会返回“函数remove_nulls中的非详尽模式”。
我尝试过更改基本情况但总是得到相同的结果。任何帮助和利用都会很棒(目前只是在学习Haskell)。
答案 0 :(得分:6)
如果您只想删除所有具有空第一个字段的对,
removeNulls xs = filter (not . null . fst) xs
会做到这一点。如果您还不熟悉(not . null . fst)
中的符号,那么编写函数\pair -> not (null (fst pair))
只是一种较短的方法。有关更多解释,请参阅this SO question。
您的原始函数似乎尝试在第二个输入列表的第一个元素之后插入第一个列表中的好元素,并且无法工作,因为它不包括第二个列表为空的情况。
答案 1 :(得分:0)
remove_nulls
应该获取列表并返回一个新列表:
remove_nulls :: [ ([String], Int) ] -> [ ([String], Int) ]
remove_nulls lst = [(x,y) | (x,y) <- lst, (not.null) x]
答案 2 :(得分: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)
答案 3 :(得分: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)