我是一个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)...对初学者的任何建议?
答案 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
然而,使用递归并不是一个好主意(除非这是你的功课)。这很容易出错,同时它已经很好地在你内部抽象(在地图和过滤器内)。