用 Maybe 递归
Recursion with Maybe
我很难尝试编写一个函数来使用递归查找两个列表的总和,如果任何列表为空,则可能为 Nothing。
以下函数的数学运算是:
Σw[i]x[i]
其中 w 和 x 是等长的 int 数组
这是我的工作代码:
example :: [Int] -> [Int] -> Int
example [] [] = 0
example (x:xs) (l:ls) = ((x*l) + (example xs ls))
这是我想要工作的想法:
example :: [Int] -> [Int] -> Maybe Int
example [] [] = Nothing
example (x:xs) (l:ls) = Just((x*l) + (example xs ls))
谢谢
你很接近,但是你对 example xs ls
returns a Maybe Int
的递归调用不能添加 Int
和 Maybe Int
(在 x*l + example xs ls
中),因此你在最后一行的错误。
你可以用fromMaybe
来处理这种情况,使用0
作为默认和:
example :: [Int] -> [Int] -> Maybe Int
example [] [] = Nothing
example (x:xs) (l:ls) = Just $ x * l + fromMaybe 0 (example xs ls)
或者(更简洁),您可以使用如下方式避免显式递归:
example [] [] = Nothing
example xl yl = Just $ sum $ zipWith (*) xl yl
请注意,您的模式匹配中有非详尽模式。两个不同长度的列表将导致模式匹配异常。
我猜你的意图是什么,不确定我是否理解正确:当两个输入列表长度不同时,你希望函数产生 Nothing
?
"happy" 基本情况是 0
就像第一次尝试一样,但提升到 Maybe
。
example [] [] = Just 0
要处理列表长度不同的情况,请包括只有 一个 列表为空的情况。对于不包括这些情况的非详尽模式匹配,您应该已经收到编译器警告。
example [] _ = Nothing
example _ [] = Nothing
那么,最后一种情况是您有两个非空列表。它看起来很像你第一次尝试的那一行,除了不是直接将加法应用于 example xs ys
,我们 fmap
在 example xs ys
上加法,利用 Maybe
是 Functor
.
这一事实
example (x : xs) (y : ys) = fmap (x * y +) (example xs ys)
用法示例:
λ> example [1,2] [3,4]
Just 11
λ> example [1,2] [3,4,5]
Nothing
顺便说一下,如果你想使用这个库,safe
将它变成单行代码是一个不错的选择。
import Safe.Exact
example xs ys = fmap sum (zipWithExactMay (*) xs ys)
我很难尝试编写一个函数来使用递归查找两个列表的总和,如果任何列表为空,则可能为 Nothing。
以下函数的数学运算是:
Σw[i]x[i]
其中 w 和 x 是等长的 int 数组
这是我的工作代码:
example :: [Int] -> [Int] -> Int
example [] [] = 0
example (x:xs) (l:ls) = ((x*l) + (example xs ls))
这是我想要工作的想法:
example :: [Int] -> [Int] -> Maybe Int
example [] [] = Nothing
example (x:xs) (l:ls) = Just((x*l) + (example xs ls))
谢谢
你很接近,但是你对 example xs ls
returns a Maybe Int
的递归调用不能添加 Int
和 Maybe Int
(在 x*l + example xs ls
中),因此你在最后一行的错误。
你可以用fromMaybe
来处理这种情况,使用0
作为默认和:
example :: [Int] -> [Int] -> Maybe Int
example [] [] = Nothing
example (x:xs) (l:ls) = Just $ x * l + fromMaybe 0 (example xs ls)
或者(更简洁),您可以使用如下方式避免显式递归:
example [] [] = Nothing
example xl yl = Just $ sum $ zipWith (*) xl yl
请注意,您的模式匹配中有非详尽模式。两个不同长度的列表将导致模式匹配异常。
我猜你的意图是什么,不确定我是否理解正确:当两个输入列表长度不同时,你希望函数产生 Nothing
?
"happy" 基本情况是 0
就像第一次尝试一样,但提升到 Maybe
。
example [] [] = Just 0
要处理列表长度不同的情况,请包括只有 一个 列表为空的情况。对于不包括这些情况的非详尽模式匹配,您应该已经收到编译器警告。
example [] _ = Nothing
example _ [] = Nothing
那么,最后一种情况是您有两个非空列表。它看起来很像你第一次尝试的那一行,除了不是直接将加法应用于 example xs ys
,我们 fmap
在 example xs ys
上加法,利用 Maybe
是 Functor
.
example (x : xs) (y : ys) = fmap (x * y +) (example xs ys)
用法示例:
λ> example [1,2] [3,4]
Just 11
λ> example [1,2] [3,4,5]
Nothing
顺便说一下,如果你想使用这个库,safe
将它变成单行代码是一个不错的选择。
import Safe.Exact
example xs ys = fmap sum (zipWithExactMay (*) xs ys)