2010-11-25 125 views
2

下面的代码编译不到风度:帮助解决这个代码在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 `]' 

我试图插入一些空格,而盈方或最后一行的后面,但它不工作。这让我更加难过,因为我不知道发生了什么。

需要帮助

UPDATE

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

例子:

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

回答

3

你的功能是很奇怪的。

  1. 最明显的是:您在let的结尾处缺少in。改为使用where
  2. 您的类型签名很奇怪。核实!
  3. 在z的定义中使用模式匹配而不是让。
  4. y不能同时是数字和列表。

它可能看起来像这样:

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] 
+0

更新已添加到帖子 – Kap 2010-11-25 05:40:42

1

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