Data.List 定义
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr f b = case f b of
Just (a,new_b) -> a : unfoldr f new_b
Nothing -> []
Run Code Online (Sandbox Code Playgroud)
有许多功能几乎可以使用unfoldr,但在列表的最后有问题.一个简单的"修复"是
unfoldr' :: (b -> Either (a,b) [a]) -> b -> [a]
unfoldr' f b = case f b of
Left (a, new_b) -> a : unfoldr' f new_b
Right r -> r
Run Code Online (Sandbox Code Playgroud)
这个功能有标准名称吗?它有不错的属性和良好的互动foldr吗?
(这更多是一条注释,带有一些代码,因此不适合)考虑您在注释中提到的测试用例,
f xs -- = zip (map reverse $ inits xs) (tails xs)
= unfoldr g (Just ([],xs))
where
g (Just (acc,xs@[])) = Just ( (acc,xs), Nothing)
g (Just (acc,xs@(x:t))) = Just ( (acc,xs), Just (x:acc, t) )
g Nothing = Nothing
Run Code Online (Sandbox Code Playgroud)
感知到的问题是结束列表的一个额外处理节拍,这迫使我们使用嵌套的Maybe. 事实上,您的函数更容易(不需要嵌套Maybe):
= unfoldr' h ([],xs)
where
h (acc,xs@[]) = Right [ (acc,xs) ] -- last tail
h (acc,xs@(x:t)) = Left ( (acc,xs), (x:acc,t) )
Run Code Online (Sandbox Code Playgroud)
但我们还可以g通过另一种方式简化代码:
= unfoldr (fmap g') (Just ([],xs))
where
g' (acc,xs@[]) = ( (acc,xs), Nothing) -- last element
g' (acc,xs@(x:t)) = ( (acc,xs), Just (x:acc, t) )
Run Code Online (Sandbox Code Playgroud)
并使用它作为此类功能的骨架,标准unfoldr仍然如此。Nothing或者也许定义中多一行代码g,那么,没有什么可担心的。
但是,如果您确实需要在列表中添加一个特殊的尾部,而不仅仅是一个元素,那么它当然无法替代。
| 归档时间: |
|
| 查看次数: |
289 次 |
| 最近记录: |