是的,另一个美元符号问题。对不起...
(我使用了搜索功能!)
我的函数编程课程教授告诉我们,美元符号
“kinda在结尾加一个括号,然后在结尾加一个括号”(用大致相同的方式对here进行了非常粗略的描述)。所以
fibs = 0 : 1 : zipWith (+) fibs $ tail fibs
应该等于
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
好吧,不是。第二件事编译正常,第一件事给出一个错误:
jkjj.hs:1:8:
Couldn't match expected type `[a1] -> [a1]' with actual type `[a0]'
The first argument of ($) takes one argument,
but its type `[a0]' has none
In the expression: 0 : 1 : zipWith (+) fibs $ tail fibs
In an equation for `fibs':
fibs = 0 : 1 : zipWith (+) fibs $ tail fibs
fibonacci.hs:1:16:
Couldn't match expected type `[a0]' with actual type `[a1] -> [a1]'
In the return type of a call of `zipWith'
Probable cause: `zipWith' is applied to too few arguments
In the second argument of `(:)', namely `zipWith (+) fibs'
In the second argument of `(:)', namely `1 : zipWith (+) fibs'
当然,由于$是一个函数,所以类似:
fibs = 0 : 1 $ zipWith (+) fibs (tail fibs)
不会起作用,所以至少我的教授给出的解释过于简单。在撰写本文时,我尝试放置括号,以使错误相同。我有:
fibs = (0 : 1 : zipWith (+) fibs) $ tail fibs
和
fibs =(0:1:zipWith(+)fibs)(tail fibs)
两者都给了我完全相同的错误消息(当然,除了列号)。为什么是这样? b $ c d等于(a b)(c d)而不是a b(c d)吗?我认为所有这些都与功能优先级和/或关联性有关,但我不知道具体细节。我不知道你怎么能看到一个函数具有什么优先级(除了尝试很多组合),我也找不到它。
我希望有人可以帮助我解决这个问题!
最佳答案
这是一个优先问题。您在这里有两个中缀运算符:
和$
。作为infix运算符,:
的优先级高于$
,因此绑定更紧密。您可以询问ghci中的优先级
>> :i :
data [] a = ... | a : [a] -- Defined in `GHC.Types`
infixr 5 :
>> :i $
($) :: (a -> b) -> a -> b
infixr 0 $
infixr
表示运算符在右侧分组(以便将a + b + c
表达式解释为a + (b + c)
),并且数字给出优先级(更高=绑定更紧密)。另外,您需要知道函数应用程序具有最高优先级(最紧密的绑定)。所以在你的两个表达中
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
被分组像
fibs = 0 : (1 : (zipWith (+) fibs (tail fibs)))
而这
fibs = 0 : 1 : zipWith (+) fibs $ tail fibs
被分组像
fibs = (0 : (1 : (zipWith (+) fibs))) $ (tail fibs)
这会给您带来错误,因为
$
左侧的表达式应该是一个函数,但就您而言,它是一个列表。