是的,另一个美元符号问题。对不起...
(我使用了搜索功能!)

我的函数编程课程教授告诉我们,美元符号
“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)

这会给您带来错误,因为$左侧的表达式应该是一个函数,但就您而言,它是一个列表。

07-25 23:25