概括haskell功能

时间:2012-01-07 14:05:42

标签: generics haskell

我应该编写带有list,element和返回位置的函数。像,

pos 2 [1, 2, 3, 2] -> [2, 4]
pos 1 [1, 2, 3, 2] -> [1]
pos 8 [1, 2, 3, 2] -> []

这就是我所做的。

--findFirstPosition :: Eq a => a -> [a] -> Maybe a
findFirstPosition val xs = case f of 
    Nothing -> Nothing 
    Just (v, i) -> Just(i)
  where f = (find (\ (v, i) -> val == v) (zip xs [1..]))

--pos :: Eq a => a -> [a] -> [Int]
pos _ [] = []
pos val xs = if (finded) 
    then concat[
           [fromJust res],
            map (\a -> a + (fromJust res)) 
            (pos val (drop  (fromJust res) xs))]
    else []  
  where 
    res = findFirstPosition val xs
    finded = (isJust res)

它的效果非常好。但是当我尝试使用函数类型(如注释中所示)时会发生错误

Could not deduce (a ~ Int)
from the context (Eq a)
  bound by the type signature for pos :: Eq a => a -> [a] -> [Int]
  at \test.hs:(63,1)-(72,29)
  `a' is a rigid type variable bound by
      the type signature for pos :: Eq a => a -> [a] -> [Int]
      at \test.hs:63:1
Expected type: Maybe Int
  Actual type: Maybe a
In the first argument of `fromJust', namely `res'
In the first argument of `drop', namely `(fromJust res)'

我该如何处理?此外,任何其他代码审查评论都受到高度赞赏。

UPD 我应该使用find函数来实现它。

2 个答案:

答案 0 :(得分:2)

findFirstPosition的类型应为

findFirstPosition :: Eq a => a -> [a] -> Maybe Int

此功能的目的是找到一个位置或索引。因此返回类型应该包含适合索引的内容,但不依赖于参数类型。

无关:你确定索引应该从1开始吗?通常是基于0的索引。

答案 1 :(得分:1)

您可以使用列表理解更加巧妙地实现这一点。

pos :: Eq a => a -> [a] -> [Int]
pos y xs = [i | (i, x) <- zip [0..] xs, y == x]

我还将其更改为使用从零开始的索引以与其他列表函数保持一致,但如果需要,您可以轻松地将此调整为从1开始。