2016-11-12 65 views
2

我有時會發現自己需要創建一個函數,將不同的函數映射到兩個值,然後將它們組合在一起。如何做到這一點,而不使用lambda?對haskell中的每個參數應用函數

我的職責是:

f :: a -> b 
g :: c -> d 
combine :: b -> d -> e 

的問題是:如何編寫\x y -> combine (f x) (g y)不使用拉姆達?

回答

4

一種替代pointfree拼寫包括通過使用curryuncurry,要麼(***)(從Control.Arrow)或bimap處理參數爲一對(從Data.Bifunctor):

GHCi> :t \combine f g -> curry (uncurry combine . (f *** g)) 
\combine f g -> curry (uncurry combine . (f *** g)) 
    :: (a1 -> b1 -> c) -> (a -> a1) -> (b -> b1) -> a -> b -> c 

注意的是,不同於jpath的建議,這ISN比非免費版本更短。

7

如果f = g您可以使用onData.Function。否則在base中沒有該組合器。搜索適當類型的堆棧顯示biSpconcatenative

biSp :: (a -> c) -> (b -> d) -> (c -> d -> e) -> a -> b -> e 

但是,如果這是你會從包中使用的唯一功能,你可能不希望依賴於只爲一個包。

除此之外,您可以使用至少略短一些的下列內容,但不會更具可讀性。

(. g) . combine . f 

或者在Data.Profunctor使用dimapprofunctors。雖然這也需要另外的套餐,但您可能已經間接依賴profunctors,因爲您使用的是lens或某些套餐取決於lens

dimap f (. g) combine 

這可以很容易地擴展到三個參數。以下所有內容都是相同的,並且從最短到最具結構的順序排列,最後兩個順序很容易將它們擴展到任意數量的參數。

dimap f (dimap g (. h)) combine3 
(dimap f . dimap g) (. h) combine3 
(dimap f . dimap g . dimap h) id combine3 

如果你想知道這個dimap做什麼。這是一個很好的教程:I love profunctors. They're so easy.

或者只是寫你自己的biSp

相關問題