如何正确定义像"任何"这样的函数

Asl*_*986 4 haskell

学习Haskell,我正在尝试编写一个takeIf给定条件和列表的函数来返回满足条件的所有列表元素.

期望输出的示例:

takeIf (>0) [] --> []
takeIf (>0) [-1, 0, 1, 2] --> [1,2]
Run Code Online (Sandbox Code Playgroud)

我试过这个定义:

takeIf cond [] = []
takeIf cond (x:xs) = if (cond x) 
                    then x:(takeIf cond xs)
                    else []:(takeIf cond xs)
Run Code Online (Sandbox Code Playgroud)

但它不起作用.

我的第一个问题是:我有

:t takeIf --> ([a] -> Bool) -> [[a]] -> [[a]]
Run Code Online (Sandbox Code Playgroud)

为什么?为什么不:

:t takeIf --> (a -> Bool) -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

如何才能使此代码生效?

这是我得到的错误:

在此输入图像描述

如果有帮助,我正在使用 ghci

sep*_*p2k 10

[]:(takeIf cond xs)
Run Code Online (Sandbox Code Playgroud)

在这里,你试图将[]作为新结果的第一个元素takeIf cond xs.由于[]是一个列表,GHC推断结果takeIf cond xs必须是列表.由于takeIf的结果与其参数具有相同的类型,因此这xs也意味着必须是列表的列表.因为x是元素xs,x因此必须是一个列表.

看起来你的[]:意思是"在列表[]中没有任何内容",但不是什么,它是空列表.[] : [],不给你[],它给你[[]].同样[] : [1,2,3]会给你[[], 1, 2, 3]- 除了它没有很好的类型,所以它真正给你的是一个类型错误.

如果你想在列表中没有任何内容,只是不要在列表中添加任何内容,即只使用someList而不是[] : someList.