略微普遍展开 [英] Slightly generalizing unfold

查看:100
本文介绍了略微普遍展开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆