留在列表中的项目,其值与列表中的位置编号一致

时间:2017-07-03 20:27:24

标签: list haskell

我需要更改列表例如:

[1,2,4,6,5,10]

到这个

[1,2,5](位置正确的元素列表)。

  1. 第一个元素值是1 - ok,
  2. 元素值为2 - ok,
  3. 第3个元素值为4但预期为3(由于索引) - 删除
  4. 等。如何解决下面附带的错误?

    我的代码:

    module Count where
    import Control.Monad.State
    
    nthel n xs = last xsxs
        where xsxs = take n xs
    
     deleteNth i items = take i items ++ drop (1 + i) items
    
     repeatNTimes 0 _ = return ()
     repeatNTimes n xs =
       do
         if (n == nthel n xs) then return()
           else deleteNth (n-1) xs
             repeatNTimes (n-1) xs
    
     list = [1,2,3,4,5]
     main = repeatNTimes (length list) list
    

    我有以下错误:

     * Couldn't match type `Int' with `()'
           Expected type: [()]
           Actual type: [Int]
    * In the expression: deleteNth (n - 2) xs
      In a stmt of a 'do' block:
        if (n == nthel n xs) then return () else deleteNth (n - 2) xs
      In the expression:
        do { if (n == nthel n xs) then return () else deleteNth (n - 2) xs;
             repeatNTimes (n - 1) xs }
    

1 个答案:

答案 0 :(得分:2)

使用它的一个非常好的方法是将功能拼接在一起。首先,您可能需要了解Data.List模块中的功能,您可以使用hoogle找到这些功能:http://hoogle.haskell.org

Data.List模块功能

我会在这里给你一点提升。我要选择的函数是zip函数:https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-List.html#v:zip,其类型为[a] -> [b] -> [(a, b)],然后是filter函数https://hackage.haskell.org/package/base-4.9.1.0/docs/Prelude.html#v:filter,其类型为(a -> Bool) -> [a] -> [a]然后是类型为map的{​​{1}}函数以及(a -> b) -> [a] -> [b]

功能组合

这些函数可以使用函数组合运算符拼接在一起:fst :: (a, b) -> a它需要两个共享公共输入/输出点的函数(在类型签名中它们分别是第二个和第一个参数; {{1然后它会将它们连接成一个单独的函数。

。}和(.) :: (b -> c) -> (a -> b) -> a -> c)然后将它们连接成一个函数。

堆叠起来 - 需要知识

为了做你想做的事情,你真的需要知道简单类型,参数化类型,范围(包括惰性无限范围会有所帮助),函数和可能的递归以及一些高阶函数以及Haskell函数是如何咖喱,并了解功能组成。添加对类型组合做什么和做什么的基本理解并没有什么坏处。

我帮助创作了一个教程,通过遵循一系列有趣的例子,这些教程可以帮助我们从使用的角度理解这些东西是如何工作的。它不会太长,一旦你理解了一些更基础的东西,你可能会发现更容易解决你的问题:http://happylearnhaskelltutorial.com - 请注意,它并没有调整教你如何构建东西,这将是以后的卷,但它应该给你足够的理解,能够至少猜到一个答案,或理解下面的答案。

答案 - 剧透

如果你想自己解决这个问题,你应该停在这里,稍后当你感到更自信时回来。但是,我将在下面提出一个可能的答案,所以不要看你是否还想知道!

a -> b

请记住,这只是实现此目的的一种方式。有更简单的解释方法,虽然它可能看起来效率低下,但Haskell有 list / stream fusion ,它将该函数编译成可以对数据进行单次传递的内容。