我正在审查我的Haskell编程课程中的旧考试,我似乎无法围绕这个功能(我认为提供的信息太少)。
给出的代码是
myId x = x
function n f
| n > 0 = f . function (n-1) f
| otherwise = myId
我知道如果我以输入2 (*2)
调用函数,我会得到一个函数作为结果。如果我用(-2) (*2) 1
调用它,我会得到结果1
。
我只是不知道怎么样?另外,我无法绕过函数的类型。
我知道这两个选项都是正确的,但我不明白为什么(可能是括号让我感到困惑)。
function :: (Num a, Ord a) => a -> (a -> a) -> a -> a
function :: (Num a, Ord b) => a -> (b -> b) -> b -> b
任何人都可以澄清我应该如何“阅读”这个功能以及我应该如何理解类型转换的工作方式(一直在阅读我在Haskell文献中的编程以及从了解你的Haskell,但现在已经进入了几天)。
答案 0 :(得分:5)
function
需要一些n
和一个函数f :: a -> a
,并将该函数与自身n
次组合,返回另一个类型为a -> a
的函数。当返回的函数应用于类型a
的值时,结果与在循环f
中执行n
的结果基本相同,使用每个前一步的输出作为输入为下一个。
如果最终参数是明确的,也许更容易看到相似性:
function :: (Ord a, Num a) -> a -> (b -> b) -> b -> b
function n f x
| n > 0 = f (function (n-1) f x)
| otherwise = x
这在功能上等同于您的无免费function
。
在Haskell中,函数f :: a -> b -> c
可以解释为“带a
和b
的函数并返回c
”或“获取a
并返回从b
到c
的函数。将函数应用于一个或多个输入时,请将每个输入视为消除函数的一个参数。在这种情况下,function 10
会返回类型为(a -> a) -> a -> a
的新函数,而function 2 (*2)
会返回类型为Num a => a -> a
的函数。
当你以这种方式想到它时,应该清楚为什么function (-2) (*2) 1
返回一个数字,而function 2 (*2)
返回一个函数。没有类型铸造正在进行;当您将三个参数function
应用于两个输入时,您将获得另一个函数而不是值,因为您没有提供计算该值所需的最终输入。