Spooky haskell函数以某种方式知道您的输入

时间:2017-04-18 00:36:55

标签: haskell

sumListV3如何运作? myFoldr需要3个args:function,base case num和list。然而它以某种方式知道列表(基于您的输入),即使它从未在内部代码中指定。

我认为sumListV2是最简单的。 sumListV3如何编译,更不用说正常运行了?

myFoldr :: (a -> b -> b) -> b -> [a] -> b
myFoldr _ baseCase [] = baseCase
myFoldr f b (x:xs) = f x (myFoldr f b xs)

sumListV2 :: [Int] -> Int
sumListV2 xs = myFoldr (+) 0 xs

sumListV3 :: [Int] -> Int
sumListV3 = myFoldr (+) 0 

2 个答案:

答案 0 :(得分:8)

Haskell中的函数是“咖喱”的。

这意味着当你有一个函数f :: a -> b -> c时,它实际上是a -> (b -> c),而f a b实际上是(f a) b(因为关联性规则)。

因此,当您运行f a b时,它首先执行f a,它会返回类型为b -> c的新函数。然后,您可以给它b并获得c类型的最终答案。

这使您可以部分应用功能:

ghci> let add :: Int -> Int -> Int ; add a b = a + b
ghci> add 2 3
5
ghci> (add 2) 3
5
ghci> let addToTwo = add 2
ghci> :t addToTwo
addToTwo :: Int -> Int
ghci> addToTwo 6
8
ghci> addToTwo 9
11

sumListV3的例子正在部分应用myFoldr。 (此处根据您的情况指定类型。)

myFoldr       :: (Int -> Int -> Int) ->  Int ->  [Int] -> Int
myFoldr       :: (Int -> Int -> Int) -> (Int -> ([Int] -> Int))
myFoldr (+)   ::                         Int -> ([Int] -> Int)
myFoldr (+) 0 ::                                 [Int] -> Int
sumListV3     ::                                 [Int] -> Int

由于sumListV3被定义为myFoldr (+) 0,因此您可以在sumListV3替换为myFoldr (+) 0的位置:

sumListV3 [1,2] 
  = (myFoldr (+) 0) [1,2]
  = myFoldr (+) 0 [1,2]

答案 1 :(得分:1)

通常在Haskell中有多种定义函数的方法。在这种情况下,您可以在参数xs

上使用(基本)模式匹配
sumListV2 :: [Int] -> Int
sumListV2 xs = myFoldr (+) 0 xs
在这种情况下,

在概念上与“通常的”C风格语法非常相似,在本例中为Javascript。

var sumListV2 =  function(xs) {
  return myFoldr(plusFunc, 0, xs)
}

或者您可以根据其他功能的组合来定义功能,也称为无点样式。

sumListV3 :: [Int] -> Int
sumListV3 = myFoldr (+) 0

在这种情况下,需要注意的是r.h.s.不是myFoldr的返回值,但是,因为myFoldr已经部分应用了*它的三个参数中的两个,所以它是一个函数,它接受剩下的一个列表。所以sumListV3被定义为:一个列表的函数。

使用bind部分应用myFold可以使用Javascript中的等效内容。

var sumListV2 = myFold.bind(null, plusFunc, 0);

关于Haskell的一个非常好的事情是它内置于语言中,因此您不需要额外的功能来进行部分应用。关于Haskell的一个棘手的问题,特别是来自其他语言,是你不需要额外的功能来进行部分应用;-)。棘手,因为模式匹配和部分应用的语法非常相似,而在其他语言中它们则截然不同。

*它没有提供整个图片,因为它更准确地深入研究currying以及Haskell中的每个函数只接受一个参数这一事实,而一个取3的函数是返回函数的函数“链”。但我发现它是一个有用的类比,特别是在与其他语言的部分应用程序进行比较时。