haskell - 使用列表理解的带有谓词的自定义过滤器函数
问题描述
我需要开发自己的过滤器功能,类似于filter
在 Haskell 中的工作方式,但使用列表理解和谓词。所以我会lcFilter (>3) [1,2,3,4,5,6,10,444,3]
输入 ghci,它会打印所有大于 3 的数字。
我的代码基于我擅长的递归示例,但我似乎无法转换为列表理解。无论我在其中放入什么,[x | x<-xs, p]
它都会接缝总是引发编译器错误。我知道这p
部分是错误的。我试过了==p
,xs==p
几乎所有我能想到的。这让我认为其他部分可能是错误的,但我真的不确定。
这是我的函数的代码lcFilter
。我不确定它是否部分或全部是错误的,所以我发布了整个内容。
lcFilter :: (a -> Bool) -> [a] -> [a]
lcFilter _ [] = []
lcFilter p (x:xs) = [x | x<-xs, p]
如果我键入lcFilter (>3) [1,2,3,4,5]
它应该[4,5]
像标准的 Haskellfilter
函数一样打印。
解决方案
这很简单
[x | x <- xs, p x]
因为p :: a -> Bool
, 和xs :: [a]
, 要获得布尔值,我们需要将函数应用于参数;并且通过我们拥有的列表理解语义x :: a
。
类型推断的应用规则是
x :: a
p :: a -> b
---------------
p x :: b
而且您不需要模式匹配,列表理解会解决这个问题。
所以总的来说,它是
lcFilter :: (a -> Bool) -> [a] -> [a]
lcFilter p xs = [x | x <- xs, p]
列表推导很有趣。他们遵循的一条规则是
[ ... | x <- (xs ++ ys), .... ] ===
[ ... | x <- xs, .... ] ++ [ ... | x <- ys , .... ]
结果,我们也有
[ ... | x <- ([y] ++ ys), .... ] ===
[ ... | x <- [y], .... ] ++ [ ... | x <- ys , .... ] ===
[ ...{x/y} | ....{x/y} ] ++ [ ... | x <- ys , .... ]
where的{x/y}
意思是“全部替换”x
y
。因此,[a,b,...,n]
您的定义将列表转换为
[ a, b, ..., n ] ===>
[ a | p a] ++ [b | p b] ++ ... ++ [n | p n ]
这可以进一步理解为 / 作为monads或monoids概念的一个很好的说明 / ,但我们将把它留到另一天。:)
推荐阅读
- html - 将值更新到 firebase
- c - 从共享对象文件 (.so) 中获取函数返回类型和参数
- html - 如何在 Laravel 中捕获显示的图像 ID
- vba - 宏 Internet 处理
- jquery - 将 .animate() 与 if/else 语句切换一起使用?
- c# - 带有 SetCustomAnimations 的片段事务在按下时崩溃:指定的孩子已经有一个父母
- javascript - 如何在 Cocos creator Java 脚本中使用 text to Speech 功能 - Android/IOS APP
- sql-server - 每个父记录的子记录重新编号
- sql - GROUP BY 中前一行的值作为列
- sql-server - “使用'BCP(批量复制程序)/批量插入'我们可以将数据从一个服务器1数据库发送到另一个服务器2数据库......吗?”