Haskell:基于索引向量的过滤,仅使用基本的高阶函数

Haskell:基于索引向量的过滤,仅使用基本的高阶函数,haskell,filter,higher-order-functions,Haskell,Filter,Higher Order Functions,问题 我有一个大小为N的向量a保存样本数据,另一个大小为M(N>M)的向量b保存指数。我希望根据b中的索引,获得一个大小为N的向量c,其中包含a中的过滤元素 问题 是否可以在不使用列表理解的情况下实现所需的函数,而只使用基本的高阶函数,如map、zipWith、filter等(更准确地说,它们的等价物是mapV、zipWithV、filterV等) 先决条件: 我使用的是Haskell嵌入式领域特定语言(,模块),仅限于一组硬件可合成函数。为了尊重设计方法,我只允许使用提供的功能(因此我不能使用

问题

我有一个大小为N的向量a保存样本数据,另一个大小为M(N>M)的向量b保存指数。我希望根据b中的索引,获得一个大小为N的向量c,其中包含a中的过滤元素

问题

是否可以在不使用列表理解的情况下实现所需的函数,而只使用基本的高阶函数,如map、zipWith、filter等(更准确地说,它们的等价物是mapV、zipWithV、filterV等)

先决条件:

我使用的是Haskell嵌入式领域特定语言(,模块),仅限于一组硬件可合成函数。为了尊重设计方法,我只允许使用提供的功能(因此我不能使用列表理解等)

免责声明: 我没有测试这段代码的功能,因为阴谋集团开始四处窃听。它对列表很有效,当我将每个向量转换为一个列表时,它应该可以很好地工作,尽管可能会出现问题


试试这个:

indexFilter :: (Num b, Eq b, Enum b) => Vector a -> Vector b -> Vector a
indexFilter vector indices = vector (map fst (filter (\x -> (snd x) `elem` (fromVector indices)) vectorMap))
 where
   vectorMap = zip (fromVector vector) [0..]

indexFilter
获取格式为
(,)
的元组列表,然后返回索引位于向量b中的所有元素的向量
vectorMap
只是a元素及其在向量中的索引的一个压缩包。

虽然提供的答案是对该问题的正确答案,但由于设计方法()强制实施的几个约束,它并没有解决我的问题,这些约束没有提到:

 indexFilter       :: (Num b, Eq b, Enum b) => Vector a 
                      -> Vector b 
                      -> Vector a
 indexFilter v idx = mapV (fst) (filterV (\x -> elemV (snd x) idx) vectorMap)
     where
       vectorMap = zipWithV (\a b -> (b, a)) (iterateV size (+1) 0) v
       size      = lengthV v
       elemV a   = foldlV (\acc x -> if x == a then True else acc) False
  • 无法使用列表(无法将其合成到其他后端)。ForSyDe提供了两个数据容器:信号(用于时间跨度)和向量(用于空间跨度)。这应确保系统综合的可分析性
  • elem
    没有ForSyDe.Shallow.Vector实现
解决方案1

仅使用库提供的内容,我找到的最短解决方案是:

indexFilter1     :: (Num b, Eq b, Enum b) => Vector a 
                     -> Vector b 
                     -> Vector (Vector a)
indexFilter1 v = mapV (\idx -> selectV idx 1 1 v)
根据进一步的使用情况,可以进一步展开输出向量

解决方案2

翻译的解决方案以满足上述约束条件:

 indexFilter       :: (Num b, Eq b, Enum b) => Vector a 
                      -> Vector b 
                      -> Vector a
 indexFilter v idx = mapV (fst) (filterV (\x -> elemV (snd x) idx) vectorMap)
     where
       vectorMap = zipWithV (\a b -> (b, a)) (iterateV size (+1) 0) v
       size      = lengthV v
       elemV a   = foldlV (\acc x -> if x == a then True else acc) False

列表理解可以相当简单地转换为
map
filter
zipWith
,等等。事实上,列表理解只是一元函数的语法糖,而你的
向量
类型可以变成一元函数,因此,您可以编写列表理解版本并打开
MonadComprehensions
。谢谢,我正在尝试您的方法,将其转化为我的问题(应用一些约束使其可合成)。另一方面,这似乎是一个很好的答案,也很有道理。@GeorgeUngureanu如果还有其他问题,请告诉我。我已将此答案标记为正确答案,因为它确实回答了我的问题。但是我没有解决我的问题,因为有几个设计方法的限制没有提到。此外,所提供的答案引发了一系列思考,从而得出了下文所述的解决方案。