鬼怪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
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的功能是功能“链条”即返回函数。但我觉得这是一个有用的比喻,尤其是在与其他语言的部分应用进行比较时。
它减少了eta。注意各种奇妙的用法,例如'plus =(+)' - 它如何知道有两个参数?减少埃塔(可以googleable的术语)。 'sumListV4 = sum'与您的例子和相同的概念更相似。 –
也许你不会因为'foo xs = myFoldr(+)0 xs'而购买,那么我们也知道'foo = myFoldr(+)0'。但是,你是否购买了其他含义?如果'foo = myFoldr(+)0'然后'foo xs = myFoldr(+)0 xs'是否有意义? –