Haskell也许是列表元素操作



我正在Haskell中学习列表操作,现在我正在Maybe列表类型上尝试各种列表操作。目前,我在Haskell 中实现了列表中元素的总和

sum :: Num a => [a] -> a
sum [] = 0
sum (a:t) = a + sum t

现在我想做同样的事情,但不是返回值,而是返回一个Maybe类型。当给定的列表为空时,它应该返回Nothing。

我想出了这个

sum :: Num a => [a] -> Maybe a
sum [] = Nothing
sum (a:t) = fmap (a+) (sum t)

但是所有非空列表给定的结果都为Nothing。

据我所知,给定的列表最终将与空列表模式匹配,因此返回Nothing。

如何修复此问题,使其返回预期值和Maybe类型。我不知道如何让它像上面的普通求和实现一样递归地工作,所以我想应该有另一种方法。我更希望只导入前奏模块,因为我仍在尝试吸收前奏模块中的内容。

问题是递归函数always使用空列表作为基本情况,因此基本情况值为alwaysNothing。您只想返回CCD_ 2,如果;根";调用接受一个空列表。否则,您需要使用singleton列表作为基本情况。

sum :: Num a =>[a] ->Maybe a
sum [] = Nothing
sum [x] = Just x
sum (a:t) = fmap (a+) (sum t)

这样,递归调用将永远不会到达sum [];任何非空列表将首先命中基本情况CCD_ 4。

另一种组织方法是使用原始的total函数作为仅对非空列表求和的帮助器,并单独处理空列表。

sum :: Num a => [a] -> Maybe a
sum [] = Nothing
sum xs = sum' xs
where sum' [] = Just 0
sum' (a:t) = fmap (a+) (sum' t)

请注意,sum'可以在空列表上调用,但仅当它最初在非空列表上被调用时

正如@chi所指出的,helper函数根本不需要使用Maybe;由于它只对非空列表求和,因此可以跳过使用fmap,正常对列表求和;只有最终结果需要封装在Just:中

sum :: Num a => [a] -> Maybe a
sum [] = Nothing
sum xs = Just (sum' xs)
where sum' [] = 0
sum' (a:t) = a + sum' t

最新更新