Haskell “哈斯克尔”;“固定”;关键字在声明递归lambda函数时失败
似乎一个函数应该有一个递归的名称(为了调用自己),那么lambda函数是如何递归的呢 我搜索了维基百科,它说这可以由一个“Y组合器”来完成。我没有太多的数学理论背景,它只是告诉我“Y-组合子”是哈斯克尔自己发现的。在Haskell语言中称为“fix”关键字,我尝试:Haskell “哈斯克尔”;“固定”;关键字在声明递归lambda函数时失败,haskell,recursion,lambda,fixpoint-combinators,Haskell,Recursion,Lambda,Fixpoint Combinators,似乎一个函数应该有一个递归的名称(为了调用自己),那么lambda函数是如何递归的呢 我搜索了维基百科,它说这可以由一个“Y组合器”来完成。我没有太多的数学理论背景,它只是告诉我“Y-组合子”是哈斯克尔自己发现的。在Haskell语言中称为“fix”关键字,我尝试: Prelude> let fact = fix (\f n -> if n == 0 then 1 else n * (f (n-1))) <interactive>:17:12: Not in scope
Prelude> let fact = fix (\f n -> if n == 0 then 1 else n * (f (n-1)))
<interactive>:17:12: Not in scope: ‘fix’
Prelude>let fact=fix(\f n->如果n==0,则1,否则n*(f(n-1)))
:17:12:不在范围内:“修复”
似乎失败了,但如何使用“fix”关键字实现我的预期目标?
fix
不是一个关键字,它是在数据.function
模块中定义的函数。因此,要使用它,必须导入该模块
import Data.Function
或在GHCi中:
:m Data.Function
fix
不是关键字,它是在Data.function
模块中定义的函数。因此,要使用它,必须导入该模块
import Data.Function
或在GHCi中:
:m Data.Function
fix
定义为:
fix :: (a -> a) -> a
fix f = let x = f x in x
因此,它扩展为f(f(f(f…))
,即输入函数f
到某个参数x
的嵌套应用程序的无限序列
您可以为lambda函数提供顶级定义,例如
factF f n = if n == 0 then 1 else n * f (n - 1)
或相当于:
factF :: (Int -> Int) -> (Int -> Int)
factF f = \n -> if n == 0 then 1 else n * f (n - 1)
您可以将此函数提供给fix
,以获得函数(Int->Int)
,即
fact :: (Int -> Int)
fact = fix factF
如果你扩展这个定义,你会得到
factF (factF (factF (factF ...)))
=> \n -> if n == 0 then 1 else (factF (factF (factF ...)))
由于懒惰,仅当n/=0
时才会评估重复应用factF
,因此应用于0
的上述函数将立即评估为1
您可以在这个扩展中看到,
factF
是作为一个参数提供给它自己的,然后它应用于n
的较小版本。由于factN
与lambda函数相同,因此也发生了相同的事情-lambda中的参数f
是lambda本身,它可以递归调用该lambda。fix
定义为:
fix :: (a -> a) -> a
fix f = let x = f x in x
因此,它扩展为f(f(f(f…))
,即输入函数f
到某个参数x
的嵌套应用程序的无限序列
您可以为lambda函数提供顶级定义,例如
factF f n = if n == 0 then 1 else n * f (n - 1)
或相当于:
factF :: (Int -> Int) -> (Int -> Int)
factF f = \n -> if n == 0 then 1 else n * f (n - 1)
您可以将此函数提供给fix
,以获得函数(Int->Int)
,即
fact :: (Int -> Int)
fact = fix factF
如果你扩展这个定义,你会得到
factF (factF (factF (factF ...)))
=> \n -> if n == 0 then 1 else (factF (factF (factF ...)))
由于懒惰,仅当n/=0
时才会评估重复应用factF
,因此应用于0
的上述函数将立即评估为1
您可以在这个扩展中看到,factF
是作为一个参数提供给它自己的,然后它应用于n
的较小版本。由于factN
与lambda函数相同,因此也发生了相同的事情-lambda中的参数f
是lambda本身,然后可以递归调用它