我是一个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 :: "
Run Code Online (Sandbox Code Playgroud)
在考虑范围时,我正在尝试编写一个从这些范围中排除数字的辅助函数,但是我遇到了很多打字问题,我不知道从哪里开始.这是我的代码:
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
Run Code Online (Sandbox Code Playgroud)
这是我的错误:
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
Run Code Online (Sandbox Code Playgroud)
(还有一些)我知道它看起来很多,但这些东西似乎是相关的,我不能为我的生活找出haskell试图告诉我的东西无法演绎(a~ [a] ])来自上下文(Ord a)......对初学者有什么建议吗?
地图的第一个参数是a -> b,而不是[a] -> [a].因此,如果要使用map,则应该使用exclude类型(a, a) -> a -> b
但是,我不明白你为什么要首先使用地图.地图项目列表,而不是过滤它.map的结果始终是与原始列表长度相同的列表.永远不会有不同的长度.
如果要筛选列表,则应使用该filter功能.它需要一个谓词和一个列表并返回过滤列表:
exclude (first, last) = filter (\x -> x >= first && x <= last)
Run Code Online (Sandbox Code Playgroud)
同时,我可以看到你试图使用尾递归来构建排除函数.如果这是你的目标,那么你也不应该使用地图.只需从代码中删除所有提及的地图,它应该是好的:
exclude (first, last) (x:t) =
| x < first && x > last = x : exclude (first, last) t
| otherwise = exclude (first, last) t
Run Code Online (Sandbox Code Playgroud)
然而,使用递归并不是一个好主意(除非这是你的功课).这很容易出错,同时它已经很好地为你在折叠内部抽象(因此在地图和过滤器内部).