我正在學習 Haskell。我被要求做的一個練習是計算一組整數的冪集的所有和,例如:
allSums [1, 2, 5] -- should be [8,3,6,1,7,2,5,0]
在閱讀了串列所屬的應用程式和函子之后,我想到了這一點。有效。
allSums :: [Int] -> [Int]
allSums [] = [0]
allSums (x:xs) =
if x == 0
then allSums xs
else ( ) <$> [x, 0] <*> allSums xs
我很震驚。它看起來很簡潔,但看起來是正確的。
我不知道該和誰說話。我的朋友和父母認為我瘋了。你怎么念<$>和<*>?你甚至如何向人們描述他們所做的事情?
uj5u.com熱心網友回復:
您將<$>和 的這種組合模式發音<*>為liftA2:
liftA2 :: Applicative f
=> (a -> b -> c) -> f a -> f b -> f c
因此,然后在你的情況f ~ [],( ) :: Num a => a -> a -> a和
liftA2 :: Num a
=> (a->a->a) -> [a] -> [a] -> [a]
-- ( ) ...
( ) <$> [x,0] <*> allSums xs
=
[(x ), (0 )] <*> allSums xs
=
liftA2 ( ) [x,0] allSums xs
=
[x r | x <- [x,0], r <- allSums xs]
并且他們在串列的情況下“做”的是形成成分的笛卡爾積式組合并將函式應用于每個組合。
在對元素求和的情況下,使用0for 元素就像完全跳過它。因此確實實作了數字冪集的總和:
allSums [x1, x2, ..., xn]
=
[x1 r | x1 <- [x1,0], r <- allSums [x2, ..., xn]]
=
[x1 r | x1 <- [x1,0], r <- [x2 r | x2 <- [x2,0], r <- allSums [x3, ..., xn]]]
=
[x1 x2 r | x1 <- [x1,0], x2 <- [x2,0], r <- allSums [x3, ..., xn]]
=
...
=
[x1 x2 ... xn r | x1 <- [x1,0], x2 <- [x2,0], ..., xn <- [xn,0], r <- [0]]
=
[x1 x2 ... xn | x1 <- [x1,0], x2 <- [x2,0], ..., xn <- [xn,0]]
uj5u.com熱心網友回復:
當我自己讀這些時,我不發音;它們只是我腦海中的一個視覺符號。如果我必須大聲說出來,我會說“eff-map” <$>(如果有歧義,可能是“eff-mapped <*>to” )和“app” (如果有歧義,可能是“applied to”),它們來自前-Applicative名稱fmap和ap。
另外,我討厭fmap大聲說出來。由于這個原因和其他原因,我可能會在精神上將其轉換為
pure ( ) <*> [x,0] <*> allSums xs
在我說之前,我只需要發音pure和(<*>)。順便說一句,我覺得這種風格并不常見,這有點令人驚訝。尤其是在跨多行傳播應用引數時,這更加統一,因為
pure f
<*> a
<*> b
<*> c
不需要a特別對待線路。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/359144.html
