如何使用 Haskell 中的 Maybe 对象递归迭代列表
How to recursively iterate over a list with Maybe objects in Haskell
我正在尝试创建一个函数 justifyList
,它接受 Maybe
个对象 ([Maybe a]
) 的列表和 return [=15] 的所有对象的列表=] 类型,丢弃参数列表中 Nothing
的任何元素。
我现在的解决方案是
justifyList :: [Maybe a] -> [a]
justifyList [] = []
justifyList (x:xs)
| (isNothing x) = justifyList xs
| otherwise = x : justifyList xs
我尝试递归遍历参数列表并递归地将当前元素 x
放入 returned 列表 [a]
,如果它是 Just
类型。
但是在解释时会产生类型不匹配错误
Couldn't match type a with Maybe a
因此我的问题是;如何递归遍历 Maybe
对象列表?如果此解决方案足够,我如何将 xs
转换为 Maybe
类型?
Pattern-match 在 Maybe
s
justifyList :: [Maybe a] -> [a]
justifyList [] = []
justifyList (Nothing:xs) = justifyList xs
justifyList (Just x:xs) = x : justifyList xs
在行 justifyList (x:xs)
x
是类型 Maybe a
然后在行 | otherwise = x : justifyList xs
你尝试添加 x::Maybe a
到列表 a
.
您需要使用模式匹配打开 Maybe
类型,以便您可以获取其中的实际值。 (我将使用显式 case
语句,因为它使逻辑更容易,但最佳做法是在函数本身中使用模式匹配 - 留作 reader 的练习)。
justifyList (x:xs) = case x of
Nothing -> justifyList xs
Just a -> a:justifyList xs
作为一般规则,只有在需要进行比较或函数评估等测试时才使用保护模式 (| = ...
)。当您只需要有关类型的一些信息时(这在实践中很常见),请改用模式匹配或 case 语句。
对于那些可能在搜索中找到它的人,我将添加最后一点,Data.Maybe 中有一个函数 catMaybes
,它已经完成了这个操作。
此类函数已存在于 Data.Maybe
module and is named catMaybes :: [Maybe a] -> [a]
。
你可以用递归来实现这个,但是用列表理解来做可能更优雅,因为这允许我们同时有效地进行模式匹配和解包,所以:
justifyList :: [Maybe a] -> [a]
justifyList xs = [ <strong>x</strong> | <strong>Just x</strong> <- xs ]
只有满足 Just x
模式的项目才会产生一个项目,因此 Just x <- xs
也会执行过滤。
如果列表的第一个元素是Nothing
,则对递归结果应用id
。如果是Just x
,则对递归结果应用(x:)
。使用 maybe
到 select 正确的功能。
justifyList [] = []
justifyList (x:xs) = (maybe id (:) x) (justifyList xs)
maybe id (:) Nothing == id
maybe id (:) (Just x) == (x:)
.
我正在尝试创建一个函数 justifyList
,它接受 Maybe
个对象 ([Maybe a]
) 的列表和 return [=15] 的所有对象的列表=] 类型,丢弃参数列表中 Nothing
的任何元素。
我现在的解决方案是
justifyList :: [Maybe a] -> [a]
justifyList [] = []
justifyList (x:xs)
| (isNothing x) = justifyList xs
| otherwise = x : justifyList xs
我尝试递归遍历参数列表并递归地将当前元素 x
放入 returned 列表 [a]
,如果它是 Just
类型。
但是在解释时会产生类型不匹配错误
Couldn't match type a with Maybe a
因此我的问题是;如何递归遍历 Maybe
对象列表?如果此解决方案足够,我如何将 xs
转换为 Maybe
类型?
Pattern-match 在 Maybe
s
justifyList :: [Maybe a] -> [a]
justifyList [] = []
justifyList (Nothing:xs) = justifyList xs
justifyList (Just x:xs) = x : justifyList xs
在行 justifyList (x:xs)
x
是类型 Maybe a
然后在行 | otherwise = x : justifyList xs
你尝试添加 x::Maybe a
到列表 a
.
您需要使用模式匹配打开 Maybe
类型,以便您可以获取其中的实际值。 (我将使用显式 case
语句,因为它使逻辑更容易,但最佳做法是在函数本身中使用模式匹配 - 留作 reader 的练习)。
justifyList (x:xs) = case x of
Nothing -> justifyList xs
Just a -> a:justifyList xs
作为一般规则,只有在需要进行比较或函数评估等测试时才使用保护模式 (| = ...
)。当您只需要有关类型的一些信息时(这在实践中很常见),请改用模式匹配或 case 语句。
对于那些可能在搜索中找到它的人,我将添加最后一点,Data.Maybe 中有一个函数 catMaybes
,它已经完成了这个操作。
此类函数已存在于 Data.Maybe
module and is named catMaybes :: [Maybe a] -> [a]
。
你可以用递归来实现这个,但是用列表理解来做可能更优雅,因为这允许我们同时有效地进行模式匹配和解包,所以:
justifyList :: [Maybe a] -> [a]
justifyList xs = [ <strong>x</strong> | <strong>Just x</strong> <- xs ]
只有满足 Just x
模式的项目才会产生一个项目,因此 Just x <- xs
也会执行过滤。
如果列表的第一个元素是Nothing
,则对递归结果应用id
。如果是Just x
,则对递归结果应用(x:)
。使用 maybe
到 select 正确的功能。
justifyList [] = []
justifyList (x:xs) = (maybe id (:) x) (justifyList xs)
maybe id (:) Nothing == id
maybe id (:) (Just x) == (x:)
.