Haskell - 如果将函数作为参数,高阶函数的输入是什么样的?

Haskell - What does the input of a higher-order function look like if it takes functions as arguments?

我正在使用 Haskell,并尝试实现一个高阶函数,但我在理解和测试该函数时遇到了困难,因为我不确定输入会是什么样子。

由于函数本身是评分作业的一部分,我无法寻求有关 writing/implementing 函数本身的帮助,因此我更改了函数名称和自定义类型名称,因此我可以使用该函数作为输入参数的示例,如果您将它们输入控制台。

search :: ([(Int,Int)] -> [[(Int,Int)]]) -> ([(Int,Int)] -> Bool) -> [[(Int,Int)]] -> Maybe [(Int,Int)]
search function1 function2 listOfIntegerPairs

function1 将整数对列表作为输入并输出包含整数对的列表列表。

function2 接受一个整数对列表并输出一个布尔值。

我不确定如何将此高阶函数的参数输入控制台。

即将函数及其参数作为参数包括在内会是这样吗?

search (function1([(0,0),(0,1)])) (function2([(0,0),(0,1)])) [(0,0),(0,1)]

此表单会产生错误,但我无法弄清楚输入参数的样子,并且无法找到说明它的任何 articles/tutorials。因此,在弄清楚输入函数参数的类型之前,我无法测试该函数。

谁能给我一些指导?我问的可能吗?

Data.List中的find函数有相似的类型。

find :: (a -> Bool) -> [a] -> Maybe a

在不透露find定义的情况下,我们可以尝试在ghci中使用它。首先,我们需要导入 Data.List,因为那是定义它的地方。

> import Data.List

传递声明的函数

find 的第一个参数表示它需要一个类型为 a -> Bool 的函数。要将参数传递给 find,我们将整个函数传递给它。我们不需要先调用那个函数,或者给那个函数参数,我们可以把这个函数当作一个普通的值,然后把整个函数传递给find。这种将函数视为普通值的能力是我们谈论语言的 "functions as first-class citizens" 时的意思;我们可以用函数做任何我们可以用所有其他类型做的事情。要传递要查找的内容,我们需要先定义它。

> let divisibleBy3 x = x `mod` 3 == 0

现在,我们将把整个 divisibleBy3 函数作为第一个参数传递给 find。作为第二个参数,我们将传递一个包含我们想要查找的内容的列表,[4, 7, 9, 10]

> find divisibleBy3 [4, 7, 9, 10]
Just 9

传递 lambda

Haskell 提供了其他方法来定义函数,该函数仅引用已定义的函数。一个 lambda 构造一个新的 anonymous function。如果构造函数的类型正确,我们可以将它作为第一个参数传递给 find.

> find (\x -> x*3 == x + 8) [1,2,3,4,5,6,7,8,9,10]
Just 4

传递一个结果

函数类型既可以作为函数的参数出现,也可以作为函数的结果出现。这意味着我们可以创建新功能的功能。我们可以将函数组合运算符 . 编写为普通的函数声明。为此,我们首先需要隐藏前奏中的定义。

> import Prelude hiding ((.))
> let f . g = \x -> f (g (x))

在右侧写一个 lambda 强调,当仅应用于两个参数时,函数组合 returns 一个函数。在我们需要函数的任何地方,我们都可以传递任何具有正确类型的表达式。这意味着我们可以将 . 的结果传递给 find。这也意味着我们可以将以这些方式定义的函数作为参数传递给 ..

> find (not . odd) [1, 1, 2, 3, 5, 8]
Just 2

> find (not . divisibleBy3 . (\x -> x*(x+1))) [2, 3, 4, 5, 6]
Just 4

通过部分申请

当我们定义一个函数时

same :: Int -> Int -> Bool
same x y = x - y == 0

same类型中的函数类型构造函数->是右结合的,这意味着右边的事物先于左边的事物组合在一起。

same :: Int -> (Int -> Bool)

加上这些括号我们可以看到same,它看起来像一个双参数的函数,可以当作一个只有一个参数的函数,Int,即returns一个函数,Int -> Bool。我们可以使用 partially applied 函数生成函数作为参数传递。

> let same x y = x - y == 0
> find (same 7) [1..10]
Just 7