在Haskell中搜索无限矢量列表的非递归方式?

时间:2015-04-07 18:52:13

标签: list haskell recursion vector

我有如下数据结构:

import qualified Data.Vector.Unboxed as V
mylist :: [V.Vector (Int, Int)]

我需要搜索这个向量列表以查找满足谓词的元素。该算法保证我会找到该元素。

到目前为止,我有这样的事情:

go []     = error "Could not find"
go pred (p:ps) =
  case V.find pred p of
    Just a  -> a
    Nothing -> go ps

这很简单,但我想摆脱递归。是否有一种结构可以让我“摆脱”#34;递归?

2 个答案:

答案 0 :(得分:5)

使用newtype包,可以方便地编写

import Control.Newtype
import Data.Monoid
import Data.Foldable

go :: Foldable f => (a -> Maybe b) -> f a -> Maybe b
go = ala' First foldMap

我认为很好地暴露了你在这个计算中使用的结构。

答案 1 :(得分:2)

在某些时候使用了递归,但您可以使用Data.Monoidmap简化此操作:

go :: (a -> Bool) -> [V.Vector a] -> Maybe a
go pred = getFirst . mconcat . map (First . V.find pred)

我建议将其保留为返回Maybe a而不是使用error,大多数人会建议不要使用error,因为它只会导致您的程序崩溃,而不是让您优雅地退出

您可以使用Data.Maybe函数实现此方法:

go pred = listToMaybe . catMaybes . map (V.find pred)

或者

go pred = listToMaybe . mapMaybe (V.find pred)

或者您可以MonadPlus使用Maybe实例(首先导入Control.Monad):

go pred = msum . map (V.find pred)

Alternative中的Control.Applicative个实例:

go pred = foldr (<|>) empty . map (V.find pred)
-- Or using foldl if you really want to

有很多方法可以解决这个问题。