如何制作自定义过滤器?

时间:2016-11-11 20:48:06

标签: haskell filter

我无法自己解决这个问题但没有成功。我正在尝试创建自己的Filter,而不是在List中包含某些东西,因为它是假的它做了一些事情。

代码

我尝试过:

myfilter :: (a -> Bool) -> [a] -> [a]
myfilter p (x:xs)
 | p x = x : myfilter p xs
 | otherwise = []:myfilter p xs

我试图让myFilter将空白[]添加到输出列表中。例如。

myFilter isIt1andOnly1[[1],[2,2],[3,4]]])

输出

应该是什么输出:

[[1], [ ], [ ], []]

内置过滤器的作用:

[[1]]

非常感谢任何帮助。

编辑:

对于我造成的任何误解,我很抱歉,但我并不是在寻找

filter (==1) [list] 

在自定义过滤器问题上更改了一点问题,而不是过滤器(== 1)[[randomlist]]

3 个答案:

答案 0 :(得分:3)

myfilter并不知道它正在使用列表列表。查看您提供的类型签名myfilter

myfilter :: (a -> Bool) -> [a] -> [a]

[a]表示"任意类型列表a&#34 ;; myfiltera一无所知。因此,在otherwise分支中,类型检查器会认为"您正在尝试输出空列表,但我不确定a实际上是列表& #34;

修复它的一种方法是调整类型签名,使其更具体地说明我们正在使用嵌套列表:

myfilter :: ([a] -> Bool) -> [[a]] -> [[a]]

您使用此代码时遇到的另一个问题是,当输入列表为空时,您已忘记处理此案例。您需要添加与空列表匹配的子句:

myfilter p [] = []

答案 1 :(得分:1)

myfilter是正确的。与filter一样,它所做的只是,过滤一个列表:它传递一些元素而一些不传递,但它永远不会改变任何元素。

而您建议在结果中包含不在原始列表中的元素。 filter无法完成此操作。但是,你有另一个常数:你永远不会改变(外部)列表的结构。所以,这是map的任务。过滤器的位置在内部列表中,因此您需要在外部列表上映射过滤。感谢currying,这在Haskell中非常容易:

Prelude> map (filter isItOne) [[1],[2],[3],[1]]
[[1],[],[],[1]]

此处,isItOne必须具有签名Integer -> Bool:它仅适用于内部列表的单个元素,而不适用于整个内部列表。这就是你实施的目标。

isItOne的几种更好的方法:

iItOne :: Integer -> Bool

isItOne x | x == 1     = True
          | otherwise  = False

isItOne x = x==1

isItOne = (==1)

事实上,您可能只是内联这个:

Prelude> map (filter (==1)) [[1],[2],[3],[1]]
[[1],[],[],[1]]

答案 2 :(得分:0)

通过这些编辑 - 我认为该功能应该有所不同,但首先解决您的问题

myfilter :: (a -> Bool) -> [[a]] -> [[a]]
myfilter _ []                   = [ ]
myfilter p ([x]:xs) | p x       = [x]: myfilter p xs
                    | otherwise = [ ]: myfilter p xs
myfilter p ( _ :xs)             = [ ]:myfilter p xs

但是在这个函数中包含你正在寻找单例列表的“逻辑”有点笨拙。我宁愿写一些类似monoidalFilter的东西 - 这是我刚刚发明的一个术语。 monoid是允许连接/加法/乘法的东西,并且有一个中性元素可以想象零或一个。

monoidalFilter :: Monoid m :: (m -> Bool) -> [m] -> [m]
monoidalFilter p = map (\x -> if p x then x else mempty)

然后monoidalFilter (==[1])就可以了解

> ghci tst.hs
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( tst.hs, interpreted )
Ok, modules loaded: Main.
*Main> monoidalFilter (==[1]) [[],[1],[1,1],[2,2]]
[[],[1],[],[]]
*Main> myfilter (==1) [[],[1],[1,1],[2,2]]
[[],[1],[],[]]