![](/img/trans.png)
[英]How does (fmap.fmap) sum Just [1,2,3] type check in Haskell?
[英]How does this Haskell code work? fmap fmap (,) <*> Just . reverse
有人會幫助解釋/分解以下代碼:
λ> fmap fmap (,) <*> Just . reverse $ "stackoverflow"
Just ("stackoverflow","wolfrevokcats")
如果有人可以引導我完成他們理解這種代碼的原理的過程,那就太好了。
讓我們嘗試解碼這種毫無意義的樣式混淆:
fmap fmap (,) <*> Just . reverse $ "stackoverflow"
第一步:如何解析? 好吧, $
優先級較低,因此
(fmap fmap (,) <*> Just . reverse) $ "stackoverflow"
另外,我猜中綴<*>
的優先級低於.
(可以使用GHCi中的文檔或:i
進行檢查)。 所以,我們得到
((fmap fmap (,)) <*> (Just . reverse)) $ "stackoverflow"
讓我們Beta減少$
((fmap fmap (,)) <*> (Just . reverse)) "stackoverflow"
因此, <*>
的結果是一個函數。 這意味着我們正在使用(->) a
應用程序。 那里, (<*>) = \\xyz -> xz (yz)
又名Lambda演算的S組合器。 我們可以beta減少:
(\z -> (fmap fmap (,)) z ((Just . reverse) z)) "stackoverflow"
更多beta,可以刪除括號:
fmap fmap (,) "stackoverflow" ((Just . reverse) "stackoverflow")
更簡化:
fmap fmap (,) "stackoverflow" (Just (reverse "stackoverflow"))
fmap fmap (,) "stackoverflow" (Just "wolfrevokcats")
現在, fmap fmap (,)
部分。 (,)
參數是一個函數,因此這意味着第一個fmap
在(->) a
函數中起作用。 在那里, fmap = (.)
。 所以,這只是對
(.) fmap (,) "stackoverflow" (Just "wolfrevokcats")
(fmap . (,)) "stackoverflow" (Just "wolfrevokcats")
(fmap ((,) "stackoverflow")) (Just "wolfrevokcats")
fmap ((,) "stackoverflow") (Just "wolfrevokcats")
現在, fmap
的第二個參數的類型為Maybe String
,因此fmap
在Maybe
函數中起作用。 在那里, fmap f (Just x) = Just (fx)
。 我們得到
Just (((,) "stackoverflow") "wolfrevokcats")
Just ((,) "stackoverflow" "wolfrevokcats")
Just ("stackoverflow", "wolfrevokcats")
結論:毫無意義的代碼通常是毫無意義的。 要解碼此代碼段,我們必須在頭上運行類型推斷器,重新調用三個特定的實例(即使它們是非常標准的),並應對優先級。 除了故意混淆之外,沒有人可以使用這種樣式。 (當然不是招聘難題!)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.