帮助在Haskell中解决此代码

时间:2010-11-25 05:16:12

标签: haskell

以下代码无法编译:

reindex :: (a -> a) -> [a]
reindex [] = []
reindex f y = let x = (zip [0..] y)
                  z = [(f m) |el <- x, let m = fst el]
              [n !! y | n <- z, (n !! y) > -1]

我收到以下错误之一:

 a)
parse error on input `['

b)
 parse error on input `]'

我试图在最后一行的前面或后面插入一些空格,但它不起作用。这让我更加不安,因为我真的不知道发生了什么。

需要帮助

更新

reindex 将函数和列表作为参数。它逐个获取列表的索引并将该函数应用于它以生成新索引。它将使用新生成的索引从原始列表中检索值以形成新列表。如果新索引超出原始列表的范围,则忽略该数字。

的示例:

Main> reindex (\x -> x + 1) [3,4,5]
[4,5]
Main> reindex (\x -> x - 2) [3,4,5]
[3]

2 个答案:

答案 0 :(得分:3)

你的功能真的很奇怪。

  1. 最明显的一点:你错过in末尾的let。请改用where
  2. 你的类型签名很奇怪。检查一下!
  3. 在z。
  4. 的定义中使用模式匹配而不是let
  5. y不能同时是数字和列表。
  6. 看起来像这样:

    reindex _ [] = []
    reindex f y  = [n !! y | n <- z, (n !! y) > -1] where
      x = (zip [0..] y)
      z = [(f m) |(m,_) <- x]
    

    但无论如何,我真的不懂代码。如果您解释一下它应该做什么,我们可能会找到一个更简单的解决方案。

    编辑:

    我会这样做你想做的事情:(如果允许其他模块)。

    import Data.List
    import Data.Function
    
    reindex f list = map snd $ sortBy (compare `on` fst) newList where
        l = length list
        newIndizes = map f [0..]
        inList (x,_) = x >= 0 && x < l
        newList = filter inList $ zip newIndizes list
    

    我认为这更容易理解和更快(但请详细说明)。

    如果函数可能列出两次值,则行为未定义。你可以添加它来修复它:

    reindex f list = map snd $ sortBy (compare `on` fst) cleanedList where
      cleanedList =  nubBy ((==) `on` fst) newList
    

    这是你的类型签名:

    reindex :: (Int -> Int) -> [a] -> [a]
    

答案 1 :(得分:1)

你的第二行看起来很奇怪。你的函数应该期望a到a的函数并返回a的列表,但是第二行中的模式只是一个列表。这对我没有意义。