函数在Haskell中起主要作用,因为它是一种函数式编程语言,与其他语言一样,Haskell确实具有自己的功能定义和声明。
函数声明由函数名称,参数列表以及其输出组成。
函数定义是您实际定义函数的地方。
让我们举一个 add 函数的示例来详细了解这个概念。
add::Integer -> Integer -> Integer --function declaration add x y= x + y --function definition main=do putStrLn "The addition of the two numbers is:" print(add 2 5) --calling a function
在这里,我们在第一行中声明了我们的函数,在第二行中,我们编写了实际的函数,该函数将带有两个参数并产生一个整数类型的输出。
与大多数其他语言一样,Haskell从 main 方法开始编译代码。我们的代码将生成以下输出-
The addition of the two numbers is: 7
模式匹配是匹配特定类型的表达式的过程,只是一种简化代码的技术,可以将这种技术实现为任何类型的Type类,If-Else可以用作模式匹配的替代选项。
模式匹配可以看作是动态多态的一种变体,在运行时,可以根据其参数列表执行不同的方法。
看一下下面的代码块。 在这里,我们使用了模式匹配技术来计算数字的阶乘。
fact::Int -> Int fact 0=1 fact n=n * fact ( n - 1 ) main=do putStrLn "The factorial of 5 is:" print (fact 5)
我们都知道如何计算数字的阶乘,编译器将开始搜索带有参数的函数" fact",如果参数不等于0,则数字将继续调用比实际参数小1的相同函数。
当参数的模式与0完全匹配时,它将调用我们的模式"事实0=1",我们的代码将产生以下输出-
The factorial of 5 is: 120
Guards是一个与模式匹配非常相似的概念, 在模式匹配中,我们通常匹配一个或多个表达式,但是我们使用防护来测试表达式的某些属性。
尽管建议对防护使用模式匹配,但是从开发人员的角度来看,防护更加易读和简单。。
fact::Integer -> Integer fact n | n == 0=1 | n /= 0=n * fact (n-1) main=do putStrLn "The factorial of 5 is:" print (fact 5)
在这里,我们声明了两个后卫,以" |"分隔并从 main 调用 fact 函数。在内部,编译器将以与模式匹配的方式相同的方式工作,以产生以下输出:
The factorial of 5 is: 120
其中是关键字或内置函数,可在运行时用于生成所需的输出,当函数计算变得复杂时,这将非常有用。
考虑一下您的输入是具有多个参数的复杂表达式的情况。在这种情况下,您可以使用" where"子句将整个表达式分解成小部分。
在下面的示例中,我们采用一个复杂的数学表达式。我们将展示如何使用Haskell找到多项式方程[x ^ 2-8x + 6]的根。
roots::(Float, Float, Float) -> (Float, Float) roots (a,b,c)=(x1, x2) where x1=e + sqrt d/(2 * a) x2=e - sqrt d/(2 * a) d=b * b - 4 * a * c e=- b/(2 * a) main=do putStrLn "The roots of our Polynomial equation are:" print (roots(1,-8,6))
注意,计算给定多项式函数的根的表达式很复杂,这很复杂,因此,我们使用 where 子句破坏了表达式。上面的代码将生成以下输出-
The roots of our Polynomial equation are: (7.1622777,0.8377223)
递归是一种函数反复调用自身的情况,Haskell不提供任何多次循环任何表达式的功能,相反,Haskell希望您将整个功能分解为不同功能的集合,并使用递归技术来实现您的功能。
在以下示例中,我们同时使用了模式匹配和递归来计算阶乘5。
fact::Int -> Int fact 0=1 fact n=n * fact ( n - 1 ) main=do putStrLn "The factorial of 5 is:" print (fact 5)
它将产生以下输出-
The factorial of 5 is: 120
到目前为止,我们已经看到,Haskell函数将一种类型作为输入,而将另一种类型作为输出,这在其他命令式语言中非常相似。 高阶函数是Haskell的一项独特功能,您可以在其中将函数用作输入或输出参数。
让我们以一个示例为例,在该示例中,我们将导入一个内置的高阶函数映射,并根据选择使用该映射来实现另一个高阶函数。
import Data.Char import Prelude hiding (map) map::(a -> b) -> [a] -> [b] map _ []=[] map func (x : abc)=func x : map func abc main=print $map toUpper "learnfk.com"
在上面的示例中,我们使用了类型类 Char 的 toUpper 函数将输入转换为大写,在这里,方法" map"将一个函数作为参数并返回所需的输出。
sh-4.3$ghc -O2 --make *.hs -o main -threaded -rtsopts sh-4.3$main "TUTORIALSPOINT.COM"
有时,我们必须编写一个在应用程序的整个生命周期中只能使用一次的函数,为了应对这种情况,Haskell开发人员使用了另一个称为 lambda表达式或 lambda函数的匿名块。
没有定义的函数称为lambda函数, Lambda函数由"\"字符表示,下面的示例,在不创建任何函数的情况下将输入值增加1。
main=do putStrLn "The successor of 4 is:" print ((\x -> x + 1) 4)
在这里,我们创建了一个没有名称的匿名函数,它以整数4作为参数,并输出输出值,我们基本上只是在操作一个功能,甚至没有正确声明它。
我们的lambda表达式将产生以下输出-
sh-4.3$main The successor of 4 is: 5
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)