有人可以指出如何将数据提供给:
twice f x = f (f x)
这是从Erik Meijer的演讲中获得的,我觉得在将数据传递给它时我只能真正理解。现在这只会导致错误。
答案 0 :(得分:2)
派生类型签名为(t -> t) -> t -> t
。传递任何匹配的参数,您将不会遇到编译器错误。一个例子是twice (+1) 0
。
答案 1 :(得分:1)
这里的主要错误是忽略twice
的类型。在Haskell中,类型非常重要,并且精确地解释了如何调用这样的函数。
twice :: (a -> a) -> a -> a
因此,该功能以这种方式工作:
a
f
a -> a
a
twice
最终生成a
因此,我们可以做到以下几点。例如,我们可以选择a = Int
。然后将函数f
定义为
myFun :: Int -> Int
myFun y = y*y + 42
然后选择x :: Int
作为10
。最后,我们可以打电话
twice myFun 10
或者,我们可以使用lambda并跳过上面的函数定义
twice (\y -> y*y + 42) 10
答案 2 :(得分:0)
为了说明,这里有三个名为erik1,erik2和erik3的函数,它们具有相同的类型签名。
erik1, erik2, erik3 ::(a -> a) -> a -> a
erik1 f x = f x
erik2 f x = f(f x) -- Equivalent to "twice"
erik3 f x = f(f(f x))
这些eriks有两个参数,第一个是函数,第二个是数字。让我们选择sqrt作为函数,选择数字为16并运行三个eriks。这是你得到的:
*Main> erik1 sqrt 16
4.0
*Main> erik2 sqrt 16
2.0
*Main> erik3 sqrt 16
1.4142135623730951
你可以尝试很多东西,比如erik3(/ 2)16 = 2,因为函数中的f允许你使用任何合适的函数。在sqrt的特定情况下,erik3等同于C:
中的此语句printf ("Eighth root of 16 = %f \n", sqrt(sqrt(sqrt(16))));
Dr. Meijer Ch 7 1:48到3:37 当我昨晚看了这个讲座时,Erik将类型签名写成两次::(a - > a) - > (a - > a)并说," 两次是一个函数,它接受a并将一个新函数从a返回到,并且通过添加一些额外的parens,它变得非常痛苦两次是更高阶的功能。"
更接近于说明的C示例:
#define eighthRoot(x) (sqrt(sqrt(sqrt(x))))
printf ("eigthtRoot(16) = %f \n", eighthRoot(16));