略微普遍展开 [英] Slightly generalizing unfold
问题描述
Data.List
define unfoldr ::(b - >可能(a,b)) - > b - > [a]
unfoldr f b =
的情况f b Just(a,new_b) - > a:unfoldr f new_b
Nothing - > []
有几个函数几乎可以用 unfoldr定义
,但在列表的最后有问题。一个简单的修正是:
unfoldr'::(b - >或者(a,b)[a]) - > b - > [a]
unfoldr'f b =
的情况f b Left(a,new_b) - > a:unfoldr'f new_b
右r - > r
此功能是否有标准名称?它有很好的属性,并且与 foldr
?
这是更多的评论,有些代码因此不适合)考虑你在评论中提到的测试用例,
<$ c $ (只是([],xs))
其中
g(Just(acc,xs) @(x,t))= Just((acc,xs),Just(x:acc,t) ))
g Nothing = Nothing
感知的问题是一个额外的处理节拍到 end 列表,这迫使我们使用嵌套的 Maybe
。事实上,你的函数更容易(不需要嵌套 Maybe
):
其中
h(acc,xs @ [])= Right [(acc,xs)] - last tail
h(acc, xs @(x:t))= Left((acc,xs),(x:acc,t))
但我们也可以用另一种方式简化 g
代码:
= unfoldr(fmap g')(Just([],xs))
其中
g'(acc,xs @ [])=((acc,xs),Nothing) - last元素
g'(acc,xs @(x:t))=((acc,xs),Just(x:acc,t))
并将其用作此类函数的框架,标准 unfoldr
仍然存在。或者,在 g
的定义中,可能还有一个> Nothing
代码行,没有什么值得关注的。 / p>
但当然,如果您真的需要在列表中添加一个特殊的尾部,而不仅仅是一个元素,那它就不是替代品。
Data.List
defines
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr f b = case f b of
Just (a,new_b) -> a : unfoldr f new_b
Nothing -> []
There are a number of functions that can almost be defined using unfoldr
, but have trouble at the very end of the list. A simple "fix" is
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
Does this function have a standard name? Does it have nice properties and interact well with foldr
?
(this is more of a comment, with some code so it doesn't fit) Consider the test case that you mention in the comments,
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
the perceived problem is with the one extra processing beat to end the list, which forces us to use the nested Maybe
. Indeed it's easier with your function (there's no need for the nested Maybe
):
= unfoldr' h ([],xs)
where
h (acc,xs@[]) = Right [ (acc,xs) ] -- last tail
h (acc,xs@(x:t)) = Left ( (acc,xs), (x:acc,t) )
But we could also simplify the g
code another way:
= 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) )
and use this as a skeleton for such functions, with the standard unfoldr
still. Or maybe one more Nothing
line of code in the definition of g
is, well, nothing to be concerned about.
But of course it's no replacement in the case where you really need to put a special tail into your list, not just one more element.
这篇关于略微普遍展开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!