映射中的Haskell错误

时间:2014-02-20 07:18:53

标签: haskell types map

我是一个haskell新手,但我正在开发一个我称之为mfilter的函数,如果它们属于传入范围,它将从列表中排除元素,如下所示:

mfilter [(3,7)] [1..10] = [1,2,8,9,10]
mfilter [(10,18), (2,5), (20,20)] [1..25] = [1,6,7,8,9,19,21,22,23,24,25]
mfilter [('0','9')] "Sat Feb 8 20:34:50 2014" = "Sat Feb :: "

在考虑范围时,我正在尝试编写一个从这些范围中排除数字的辅助函数,但是我遇到了很多打字问题,我不知道从哪里开始。这是我的代码:

mfilter :: Ord a => [(a, a)] -> [a] -> [a]
mfilter (range:t) list = mfilter t (map (exclude range) list)

exclude :: Ord a => (a, a) -> [a] -> [a]
exclude _ [] = []
exclude (first, last) (x:t)
    | x < first && x > last = x : map (exclude (first, last)) t
    | otherwise = map (exclude (first, last)) t

这是我的错误:

Prelude> :l mfilter.hs
[1 of 1] Compiling Main             ( mfilter.hs, interpreted )

mfilter.hs:5:42:
Could not deduce (a ~ [a])
from the context (Ord a)
  bound by the type signature for
             mfilter :: Ord a => [(a, a)] -> [a] -> [a]
  at mfilter.hs:4:12-42
  `a' is a rigid type variable bound by
      the type signature for mfilter :: Ord a => [(a, a)] -> [a] -> [a]
      at mfilter.hs:4:12
Expected type: [a] -> a
  Actual type: [a] -> [a]
In the return type of a call of `exclude'
In the first argument of `map', namely `(exclude range)'
In the second argument of `mfilter', namely
  `(map (exclude range) list)'

mfilter.hs:5:57:
Could not deduce (a ~ [a])
from the context (Ord a)
  bound by the type signature for
             mfilter :: Ord a => [(a, a)] -> [a] -> [a]
  at mfilter.hs:4:12-42
  `a' is a rigid type variable bound by
      the type signature for mfilter :: Ord a => [(a, a)] -> [a] -> [a]
      at mfilter.hs:4:12
Expected type: [[a]]
  Actual type: [a]
In the second argument of `map', namely `list'
In the second argument of `mfilter', namely
  `(map (exclude range) list)'
In the expression: mfilter t (map (exclude range) list)

mfilter.hs:11:44:
Could not deduce (a ~ [a])
from the context (Ord a)
  bound by the type signature for
             exclude :: Ord a => (a, a) -> [a] -> [a]
  at mfilter.hs:8:12-40
  `a' is a rigid type variable bound by
      the type signature for exclude :: Ord a => (a, a) -> [a] -> [a]
      at mfilter.hs:8:12
Expected type: [a] -> a
  Actual type: [a] -> [a]
In the return type of a call of `exclude'
In the first argument of `map', namely `(exclude (first, last))'
In the second argument of `(:)', namely
  `map (exclude (first, last)) t'

mfilter.hs:11:67:
Could not deduce (a ~ [a])
from the context (Ord a)
  bound by the type signature for
             exclude :: Ord a => (a, a) -> [a] -> [a]
  at mfilter.hs:8:12-40
  `a' is a rigid type variable bound by
      the type signature for exclude :: Ord a => (a, a) -> [a] -> [a]
      at mfilter.hs:8:12
Expected type: [[a]]
  Actual type: [a]
In the second argument of `map', namely `t'
In the second argument of `(:)', namely
  `map (exclude (first, last)) t'
In the expression: x : map (exclude (first, last)) t

(以及更多)我知道它看起来很多,但这些事情似乎是相关的,我不能为我的生活弄清楚haskell试图告诉我什么无法演绎(a 〜[a]) 从上下文(Ord a)...对初学者的任何建议?

1 个答案:

答案 0 :(得分:6)

地图的第一个参数是a -> b,而不是[a] -> [a]。因此,如果要使用地图,则排除类型应为(a, a) -> a -> b

但是,我不明白你为什么要首先使用地图。地图项目列表,而不是过滤它。 map的结果始终是与原始列表长度相同的列表。永远不会有不同的长度。

如果要过滤列表,则应使用filter功能。它需要一个谓词和一个列表,并返回过滤后的列表:

exclude (first, last) = filter (\x -> x >= first && x <= last)

同时,我可以看到你试图使用尾递归来构建exclude函数。如果这是你的目标,那么你也不应该使用地图。只需从代码中删除所有提及的地图,就可以了:

exclude (first, last) (x:t) =
    | x < first && x > last = x : exclude (first, last) t
    | otherwise = exclude (first, last) t

然而,使用递归并不是一个好主意(除非这是你的功课)。这很容易出错,同时它已经很好地在你内部抽象(在地图和过滤器内)。