2011-10-10 75 views

回答

5

是的,這就是:

chainl1 p op = foldl (flip ($)) <$> p <*> many (flip <$> op <*> p) 

的想法是,你必須分析p (op p)*和評估它作爲(...(((p) op p) op p)...)

這可能有助於拓展定義了一下:

chainl1 p op = foldl (\x f -> f x) <$> p <*> many ((\f y -> flip f y) <$> op <*> p) 

由於對opp進行解析,結果被立即應用,但由於pop右操作數,它需要一個flip

所以,many (flip <$> op <*> p)結果類型爲f [a -> a]。然後通過foldl從左到右應用該功能列表,初始值爲p

+0

你願意解釋一下嗎?爲什麼摺疊和翻轉? – adamse

0

醜但等效Applicative定義:

chainl1 p op = 
    p <**> 
    rest 
    where 
    rest = flip <$> op <*> 
      p <**> 
      pure (.) <*> rest 
     <|> pure id 

相反左側參數x明確的傳遞到右手側op,這種應用形式「鏈」 op的部分地施加到其右經由側參數(因此flip <$> op <*> p)擡起組合子(.)然後應用經由(<**>)最左邊p到所得rest :: Alternative f => f (a -> a)

+0

當我嘗試這與'chainl1(讀<$>許多位)((+)<$符 '+' <|>(*)<$字符 '*')'的' 「1 + 2 * 3 + 4」'我得到17而不是13. –

+0

它需要'flip(。)'而不是'(。)',那麼它就可以正常工作。 –

相關問題