【问题标题】:How to filter a list with another mutable vector in haskell如何在haskell中使用另一个可变向量过滤列表
【发布时间】:2014-08-22 21:51:37
【问题描述】:

我是 Haskell 的新手。我想在 Haskell 中实现以下 python 程序。

a = [1,2,3,6,7,12,45,54,2,12,10]
b = [1,2,3,6,7,8]
c = [ i for i in b if a[i] % 2 == 0 ]
print c

我希望 a 成为 Haskell 中的 Data.Vector.Mutable。 所以我写了类似的东西

let a1 = fromList ([1,2,3,6,7,12,45,54,2,12,10] :: [Int])
let b = [1,2,3,6,7,8]
let c = [ i | i <- b, filter i a1 ] 
print c

但是我不知道如何实现 filter 。 我知道我应该 x &lt;- thaw a1y &lt;- read x i 然后检查 y。 但是如何将它们组装在一起呢?

【问题讨论】:

  • 如果你是 Haskell 的新手,你应该使用突变。告诉我们你想做什么,也许我们可以告诉你如何在没有突变的情况下做到这一点。

标签: list haskell vector filter


【解决方案1】:

假设a :: MVector s Intb :: [Int] 和您的结果应该是c :: m [Int],其中m 是一些单子,因为我们使用的是可变向量。现在,我们只需要一个合适的谓词:

-- evenVM :: PrimMonad m => MVector (PrimState m) Int -> Int -> m Bool
evenVM v i = do
    if (M.length v) < i || i <= 0
      then return False
      else fmap even $ M.read v (i - 1)

evenVM a 的类型为 PrimMonad m =&gt; Int -&gt; m Bool。因此,它可以与filterM(来自Control.Monad)一起使用,因为每个PrimMonad 也是Monad

c = filterM (evenVM a) b

thaw 如果a 确实是一个可变向量,则不需要。如果a 是一个非可变向量,您可以使用filter 和与上述几乎相同的方法。

【讨论】:

    【解决方案2】:

    您必须使用 Vector 的 zip 来索引元素并相应地过滤它们。

    import Data.Vector
    import Prelude hiding(zip, filter, elem, map, length)
    
    main :: IO ()
    main = do
        let a = fromList [1,2,3,6,7,12,45,54,2,12,10]
        let a' = fromList [0..(length a)]
        let b = fromList [1,2,3,6,7,8]
        let c = map snd $ filter (\(x,y) -> (y `elem` b) && x `mod` 2 == 0) (zip a a')
        print c
    

    在 ghci 中:

    ghci > main
    fromList [1,3,7,8]
    

    【讨论】:

    • ifilter 在过滤时为您提供索引。
    • a1 必须是 Data.Vector.Mutable
    【解决方案3】:

    您可以将过滤器与地图结合使用。

    let a = [1,2,3,6,7,12,45,54,2,12,10]
        b = [1,2,3,6,7,8] :: [Int]
    in filter even $ map (a !!)  b
    

    如果你需要 Vector 中的这个,你可以添加几个 fromList:

    import qualified Data.Vector V 
    
    let a = V.fromList [1,2,3,6,7,12,45,54,2,12,10]
        b = V.fromList ([1,2,3,6,7,8] :: [Int])
    in V.filter even $ V.map (a V.!)  b
    

    如果你更喜欢单子版本:

    do
       a <- V.fromList [1,2,3,6,7,12,45,54,2,12,10]
       b <- V.fromList ([1,2,3,6,7,8] :: [Int])
       V.filter even (return (a V.! b))
    

    【讨论】:

    • OP 想要它用于Vector
    • 更新了矢量添加。这并没有改变很多声明。
    • 这将过滤a中的所有偶数元素,其索引也在b中。但是,原始代码需要 ba 中偶数元素的所有索引之间的交集。
    • 嗨@mathk 我需要 a1 是 Data.Vector.Mutable。那你就不能用了!或者 !!。而且我没有在 Data.Vector.Mutable 中看到过滤器功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    • 2021-08-19
    • 1970-01-01
    相关资源
    最近更新 更多