[英]How to implement f (g x) (h x) point-freely in Haskell?
從這個答案中,我們將學習如何在Haskell中無意義地實現函數\\xyz -> fx (gyz)
,其中f
和g
是函數。 我的問題是
如何在Haskell中以無點方式編寫函數
\\x -> f (gx) (hx)
?f
g
h
是定義f (gx) (hx)
的函數。
我目前想到的想法如下。
uncurry f (mapTuple ($ x) (g, h))
但是,幾次嘗試表明這是錯誤的。 甚至零件map ($ x) [g, h]
也可疑:如果g
和h
具有不同的范圍怎么辦?
另外,可讀性在這里不是太大的問題。
真誠的感謝您的幫助。
箭頭版本為
uncurry f . (g &&& h)
要么
(g &&& h) >>> uncurry f
如圖所示:
g ────
╱ ╲
──── &&& >>> uncurry f ───
╲ ╱
h ────
正如melpomene建議的那樣, \\x -> f (gx) (hx)
等同於liftM2 fgh
。
如果您對如何將Haskell代碼轉換為無點Haskell代碼有疑問,可以嘗試Pointfree.io 。
它是一個很棒的工具,通常會告訴您何時不使用無點代碼,因為有時它會變得完全不可讀:-)
這僅用於收集和整理評論中的答案。 根據@PetrPudlák評論中的鏈接中的抽象消除過程,我們還可以編寫
S (S (K f) (S (K g) I)) (S (K h) I),
或者,經過eta減少后,
S (S (K f) g) h,
哪里
S x y z = x z (y z)
K x y = x
特別是在Haskell中,感謝@melpomene指出了這一點, S
的角色由ap
扮演, K
的角色由const
扮演。 因此我們可以寫
ap (ap (const f) g) h
實際上,我們可以進一步減少:
ap (const f) g = f . g
所以我們的函數可以寫成:
ap (f . g) h
如果轉換為應用風格,我們將獲得:
f <$> g <*> h
然后可以將此系統化方法應用於所有lambda項,並給出無點樣式。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.