如Erik Meijer讲座7所述,向Haskell提供两次数据

时间:2017-12-27 07:54:58

标签: function haskell

有人可以指出如何将数据提供给:

twice f x = f (f x)

这是从Erik Meijer的演讲中获得的,我觉得在将数据传递给它时我只能真正理解。现在这只会导致错误。

3 个答案:

答案 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));