鬼怪haskell功能,不知何故知道你的输入

问题描述:

sumListV3如何运作? myFoldr需要3个参数:函数,基数大小写和列表。然而它以某种方式知道列表(基于你的输入),即使它在内部代码中从未被指定过。鬼怪haskell功能,不知何故知道你的输入

我认为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 
+1

它减少了eta。注意各种奇妙的用法,例如'plus =(+)' - 它如何知道有两个参数?减少埃塔(可以googleable的术语)。 'sumListV4 = sum'与您的例子和相同的概念更相似。 –

+0

也许你不会因为'foo xs = myFoldr(+)0 xs'而购买,那么我们也知道'foo = myFoldr(+)0'。但是,你是否购买了其他含义?如果'foo = myFoldr(+)0'然后'foo xs = myFoldr(+)0 xs'是否有意义? –

Haskell中的函数是“curried”的。

这意味着,当你有一个函数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,您可以在地方myFoldr (+) 0更换sumListV3那里它被称为:

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

通常有定义的多种方式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每个函数只需要一个参数的事实,而这需要3的功能是功能“链条”即返回函数。但我觉得这是一个有用的比喻,尤其是在与其他语言的部分应用进行比较时。