[英]Is there a way to make h (f x) (g x) point-free in Haskell?
我猜想我想要J的叉功能。 有沒有辦法做到這一點?
這是,使用所謂的適用風格,
h <$> f <*> g
使用Control.Applicative
<$>
和<*>
。
另一種方法是將h
提升到(->) r
applicative functor中
liftA2 h f g
這背后的直覺是,如果
h :: a -> b -> c
-- then --
liftA2 h :: (r -> a) -> (r -> b) -> r -> c
所以提升版本需要兩個函數r -> something
而不是實際的something
,然后輸入一個r
來從r
中獲取something
。
liftA*
和<$>
和<*>
的相應組合是等效的。
雖然@kqr具有基於((->) a)
的Applicative
實例的更實用的解決方案,但我們也可以在“pipey”方法中討論它
+----- f ------+
/ \
<---- h +------< x
\ /
+----- g ------+
它提供了一種非常有組織的無點程序。 我們將使用Control.Arrow
工具創建此程序。
首先,我們使用Haskell中常見的缺失函數diag
或dup
來獲取圖表中最右邊的部分
--+
\
+----- x dup :: x -> (x, x)
/ dup x = (x, x)
--+
然后使用Control.Arrow
的(***)
組合器創建中間
----- f ----- (***) :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
f :: (a -> b)
g :: (c -> d)
----- g ----- f *** g :: (a, c) -> (b, d)
然后左側正是uncurry
為我們做
+-- uncurry :: (a -> b -> c) -> (a, b) -> c
/ h :: (a -> b -> c)
h uncurry h :: (a, b) -> c
\
+--
然后將它們連接在一起我們可以用非常合成的樣式擦除x
點。
m :: (a -> b -> c) -> (x -> a) -> (x -> b) -> x -> c
m h f g = uncurry h . (f *** g) . dup
+------ f ----+
/ \
<----- h +-----------< x (eta reduced)
\ /
+------ g ----+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.