我想知道:寫這個:
(<$>) :: (a -> b) -> Parser a -> Parser b
(<$>) f p1 s = case p1 s of
Just (r1 , s') -> Just (f r1, s')
Nothing -> Nothing
而不是這個:
(<$>) :: (a -> b) -> Parser a -> Parser b
f <$> p1 = \s -> case p1 s of
Just (r1 , s') -> Just (f r1, s')
Nothing -> Nothing
改變什么?
uj5u.com熱心網友回復:
不,它不會改變任何東西,但是。
你實際上同時改變了兩件事。首先是在定義函式時從前綴切換到中綴;另一種方法是在 lambda 中從將所有引數都放在左側切換到在右側放置一個。
從前綴切換到中綴永遠不會改變任何東西。所以如果你這樣做了:
(<$>) f p1 s = ...
VS.
(f <$> p1) s = ...
不會,但在我的答案中。
在這種情況下,從左邊的引數切換到右邊的引數沒有任何改變。但是,有兩件事可以導致該更改實際執行某些操作。首先,如果沒有型別簽名,并且 RHS 上的引數之一具有 typeclass-polymorphic 型別,則該型別將成為錯誤或單態型別。這是單態限制;請參閱什么是單態限制?更多細節。
其次,對于 GHC 編譯的程式,如果RHS 上有一個letorwhere塊沒有提到移動到 RHS 的變數,那么塊中的值可能會被計算和存盤,而不是在每次呼叫函式時重新計算. 例如,以下兩個定義是完全等價的:
f :: Int -> Int
f x = let y = 3 5 in y
VS.
f = \x -> let y = 3 5 in y
但是這些對并不等價:
f :: Int -> Int
f x = let y = 3 5 in y
VS.
f = let y = 3 5 in \x -> y
f :: Int -> Int
f x = y where y = 3 5
VS.
f = \x -> y where y = 3 5
在這兩種情況下,8每次呼叫時都會為該對中的第一個呼叫重新計算該值,但在第一次呼叫時計算一次,并在以后的呼叫中為該對中的第二個呼叫存盤并重用該值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316874.html
標籤:哈斯克尔
