接受函数和列表并返回布尔值的函数

Per*_*eus 3 haskell functional-programming function

我是Haskell和函数式编程的新手.我正在尝试执行以下任务:

创建一个接受函数和列表的函数,如果函数对列表中的至少一个项返回true,则返回true,否则返回false.应该多态地工作.

我已经搜索了许多方法,包括Prelude和any函数

any :: Foldable t => (a -> Bool) -> t a -> Bool
Run Code Online (Sandbox Code Playgroud)

但是,我正在努力实施它们.这就是我所拥有的:

list = [2,3,45,17,78]

checkMatch :: Int -> Bool 
checkMatch x 
    | x `elem` list = True
    | otherwise = False

main = do
    print (checkMatch 45)
Run Code Online (Sandbox Code Playgroud)

有关如何使用Prelude或任何函数执行此任务的任何帮助.不要只是提供答案,请解释程序.问候.

Dav*_*lor 6

好的.不是一个完整的答案,因为你想自己解决问题,但有些提示.

我强烈建议你先编写类型签名,直到你得到一个编译和处理一些案例的shell,然后填写函数定义.所以让我们从正确的类型签名开始吧.

在Haskell中,如果你想要一个带有任何类型参数的函数,你可以用不同的小写名称命名每个类型,通常是一个字母.特定类型具有大写名称,泛型类型为小写字母.因此,接受任何类型的参数并返回Bool的函数将具有类型签名a -> Bool.对于第二个参数,您需要列出一些任意类型的元素.您希望将其元素传递给您的函数,因此它必须包含我们调用的函数域相同的类型a.(如果它可以保存任何内容,我们会选择另一个小写名称,例如b.)您将该列表类型写为[a].你想要退货Bool.

因此,您的类型签名应该是(a -> Bool) -> [a] -> Bool.通常当我们编写一个对列表进行操作的函数时,一个好的方法是尾递归,我们将列表拆分为其头部和尾部(x:xs),执行某些操作x,然后再次调用该函数,xs直到最终得到一个空列表.您使用模板防护装置处于正确的轨道上,因此您可以从以下骨架开始:

checkMatch :: (a -> Bool) -> [a] -> Bool
checkMatch _ [] = _
checkMatch f (x:xs) | f x       = _
                    | otherwise = _

main :: IO()
main = do
  let shouldBeFalse = [1,3,5,7,9] :: [Int]
  let shouldBeTrue = [1..10] :: [Int]

  print (checkMatch (== " ") []) -- Does the empty string contain a space?
  print (checkMatch even shouldBeFalse)
  print (checkMatch even shouldBeTrue)
Run Code Online (Sandbox Code Playgroud)

如果你编译它,GHC会告诉你它在程序中找到了三个"洞",它们是第_2,3和4行等号右侧的三个符号.(_在左边的图案中)等号表示不同的东西:当列表为空时我们不关心函数参数是什么.为什么会这样?)它还会告诉你填充每个孔所需的类型是返回的表达式Bool.它还将为您提供具有该类型的本地函数和变量的列表.如果您尝试部分填充其中一个孔,请使用f _checkMatch _ _,它将告诉您填写所创建的新孔所需的类型.

使用正确的程序逻辑填写所有孔,您的程序将起作用.