Haskell 可能是列表元素操作
Haskell Maybe list element operations
我正在 Haskell 中学习列表操作,现在我正在尝试对 Maybe 列表类型进行各种列表操作。目前,我在 Haskell
中实现了列表中元素总和的实现
sum :: Num a => [a] -> a
sum [] = 0
sum (a:t) = a + sum t
现在我想做同样的事情,但不是 return 值,而是 return Maybe 类型。当给定的列表为空时,它应该 return Nothing.
我想到了这个
sum :: Num a => [a] -> Maybe a
sum [] = Nothing
sum (a:t) = fmap (a+) (sum t)
但是给定的所有非空列表的结果为 Nothing。
据我了解,给定的列表最终将与空列表进行模式匹配,因此 return 什么都没有。
如何解决此问题,使其 return 成为预期值和 Maybe 类型。我无法弄清楚如何使它像上面的正常 sum 实现一样递归工作,所以我想应该有另一种方法。如果只导入 Prelude 模块会更好,因为我仍在尝试吸收 Prelude 模块中的内容。
问题是你的递归函数 always 使用空列表作为基本情况,所以你的基本情况值是 always Nothing
。如果“根”调用采用空列表,您只想 return Nothing
。否则,您想使用单例列表作为基本案例。
sum :: Num a => [a] -> Maybe a
sum [] = Nothing
<b>sum [x] = Just x</b>
sum (a:t) = fmap (a+) (sum t)
这样,sum []
将永远不会被递归调用到达;任何 non-empty 列表都会首先达到基本情况 sum [x]
。
另一种组织方式是使用您原来的总计函数作为仅对 non-empty 列表求和的助手,并单独处理空列表。
sum :: Num a => [a] -> Maybe a
sum [] = Nothing
sum xs = sum' xs
where sum' [] = Just 0
sum' (a:t) = fmap (a+) (sum' t)
请注意,sum'
可以在空列表上调用,但 只能在 最初在 non-empty 列表上调用。
正如@chi 指出的那样,辅助函数根本不需要使用 Maybe
;因为它只对 non-empty 列表求和,所以你可以跳过使用 fmap
并正常对列表求和;只需要将最终结果包裹在 Just
:
sum :: Num a => [a] -> Maybe a
sum [] = Nothing
sum xs = Just (sum' xs)
where sum' [] = 0
sum' (a:t) = a + sum' t
我正在 Haskell 中学习列表操作,现在我正在尝试对 Maybe 列表类型进行各种列表操作。目前,我在 Haskell
中实现了列表中元素总和的实现sum :: Num a => [a] -> a
sum [] = 0
sum (a:t) = a + sum t
现在我想做同样的事情,但不是 return 值,而是 return Maybe 类型。当给定的列表为空时,它应该 return Nothing.
我想到了这个
sum :: Num a => [a] -> Maybe a
sum [] = Nothing
sum (a:t) = fmap (a+) (sum t)
但是给定的所有非空列表的结果为 Nothing。
据我了解,给定的列表最终将与空列表进行模式匹配,因此 return 什么都没有。
如何解决此问题,使其 return 成为预期值和 Maybe 类型。我无法弄清楚如何使它像上面的正常 sum 实现一样递归工作,所以我想应该有另一种方法。如果只导入 Prelude 模块会更好,因为我仍在尝试吸收 Prelude 模块中的内容。
问题是你的递归函数 always 使用空列表作为基本情况,所以你的基本情况值是 always Nothing
。如果“根”调用采用空列表,您只想 return Nothing
。否则,您想使用单例列表作为基本案例。
sum :: Num a => [a] -> Maybe a
sum [] = Nothing
<b>sum [x] = Just x</b>
sum (a:t) = fmap (a+) (sum t)
这样,sum []
将永远不会被递归调用到达;任何 non-empty 列表都会首先达到基本情况 sum [x]
。
另一种组织方式是使用您原来的总计函数作为仅对 non-empty 列表求和的助手,并单独处理空列表。
sum :: Num a => [a] -> Maybe a
sum [] = Nothing
sum xs = sum' xs
where sum' [] = Just 0
sum' (a:t) = fmap (a+) (sum' t)
请注意,sum'
可以在空列表上调用,但 只能在 最初在 non-empty 列表上调用。
正如@chi 指出的那样,辅助函数根本不需要使用 Maybe
;因为它只对 non-empty 列表求和,所以你可以跳过使用 fmap
并正常对列表求和;只需要将最终结果包裹在 Just
:
sum :: Num a => [a] -> Maybe a
sum [] = Nothing
sum xs = Just (sum' xs)
where sum' [] = 0
sum' (a:t) = a + sum' t