考慮以下功能:在Haskell monad/left-lifting中使用純函數?
foo =
[1,2,3] >>=
return . (*2) . (+1)
爲了更好的可讀性和邏輯,我想(*2)
和(+1)
移動我的純函數的返回的左側。我可以這樣實現這一點:
infixr 9 <.
(<.) :: (a -> b) -> (b -> c) -> (a -> c)
(<.) f g = g . f
bar =
[1,2,3] >>=
(+1) <.
(*2) <.
return
不過,我不喜歡的(<.)
右關聯性。
讓我們介紹一個功能leftLift
:
leftLift :: Monad m => (a -> b) -> a -> m b
leftLift f = return . f
baz =
[1,2,3] >>=
leftLift (+1) >>=
leftLift (*2) >>=
return
我很喜歡這一點。另一種可能性是定義的bind
變體:
infixl 1 >>$
(>>$) :: Monad m => m a -> (a -> b) -> m b
(>>$) m f = m >>= return . f
qux =
[1,2,3] >>$
(+1) >>$
(*2) >>=
return
我不知道這是否是一個好主意,因爲它不會允許我使用do
符號我應該希望如此。 leftLift
我可以do
使用:
bazDo = do
x <- [1,2,3]
y <- leftLift (+1) x
z <- leftLift (*2) y
return z
我沒有找到的leftLift
上的簽名Hoogle功能。這樣的功能是否存在?如果它叫什麼?如果不是,我應該怎麼稱呼它?什麼是我正在嘗試做的最習慣的方式?
編輯:這是一個被@鄧祿普的回答以下的啓發版本:
infixl 4 <&>
(<&>) :: Functor f => f a -> (a -> b) -> f b
(<&>) = flip fmap
blah =
[1,2,3] <&>
(+1) <&>
(*2) >>=
return
我還要補充一點,我是一個bind
後-variant,因爲我想寫我的代碼點免費樣式。對於do
-notation,我想我不需要「假裝」我做了任何單調的事情,所以我可以使用let
s。
我發現自己使用'= <比'>> ='更經常地與組成和普通應用保持一致。這很好地避免了第一個例子中的方向反轉。 – Ben
這很好,我沒有意識到這一點。然後我可以寫回報。 (* 2)。 (+1)= << [1,2,3]'。而且,是的,正如@ user2297560所說,可讀性是非常主觀的。 –