我只是想知道我们怎么知道哪些函数需要括号()而哪些函数不需要?例如
replicate 100 (product (map (*3) (zipWith max [1,2,3,4,5] [4,5,6,7,8])))
Run Code Online (Sandbox Code Playgroud)
工作良好.但
replicate 100 (product (map (*3) (zipWith (max [1,2,3,4,5] [4,5,6,7,8]))))
Run Code Online (Sandbox Code Playgroud)
不起作用.这是因为我为zipWith添加了一组括号.在这个小例子中,zipWith和max没有括号,但是复制,产品和地图都有.一般来说,有一种方法可以知道/确定哪些功能需要括号,哪些功能不需要.
Rod*_*iro 12
函数应用程序是左关联的.所以,当你写一个像这样的表达式时:
f g h x
Run Code Online (Sandbox Code Playgroud)
它的意思是:
((f g) h) x
Run Code Online (Sandbox Code Playgroud)
而且这种类型zipWith提供了一个线索:
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Run Code Online (Sandbox Code Playgroud)
它说zipWith有3个参数:一个函数和两个列表.
当你写:
zipWith (max [1,2,3,4,5] [4,5,6,7,8])
Run Code Online (Sandbox Code Playgroud)
口译员会理解这一点
max [1,2,3,4,5] [4,5,6,7,8]
Run Code Online (Sandbox Code Playgroud)
将是zipWith的第一个参数,类型不正确.需要注意的是,zipWith需要一个两个参数的函数作为它的第一个参数,并且正如@Cubic所指出的那样,max [1,2,3,4,5] [4,5,6,7,8]它将根据通常的字典顺序返回这两个列表之间的最大值[a],对于某些类型a,它是Ord和的实例Num.说,因为你试图传递一个类型的值,错误变得明显
(Num a, Ord a) => [a]
Run Code Online (Sandbox Code Playgroud)
其中type的值
(a -> b -> c)
Run Code Online (Sandbox Code Playgroud)
是期待.
罗德里戈给出了正确的答案。我只想补充一点,认为某些函数需要括号而其他函数不需要括号是一种误解。
这就像在学校数学中:
3 * (4+5)
Run Code Online (Sandbox Code Playgroud)
这根本就不是那么的情况下+表达需要的括号*表达式不需要他们一般。
在 Haskell 中,你总是可以完全不用括号。每当您需要将表达式括在括号中时,替代方法是引入本地名称并将其绑定到该表达式,然后使用名称而不是表达式。
在你的例子中:
replicate 100 (product (map (*3) (zipWith max [1,2,3,4,5] [4,5,6,7,8])))
let list1 = product list2
list2 = map thrice list3
thrice x = x*3
list3 = zipWith max [1,2,3,4,5] [4,5,6,7,8]
in replicate 100 list1
Run Code Online (Sandbox Code Playgroud)
事实上,我经常这样自上而下地编写函数:
foo x y z = result
where
result = ...
...
Run Code Online (Sandbox Code Playgroud)
但是,如前所述,由函数应用程序组成的表达式也可以通过使用(.)and来编写不带括号的表达式($),在这种情况下,自上而下的方法可能过于冗长,下面会更清楚(因为新引入的名称没有噪音):
replicate 100
. product
. map (*3)
$ zipWith max [1..5] [4..8]
Run Code Online (Sandbox Code Playgroud)