簡體   English   中英

如何在Haskell中自由地實現f(gx)(hx)?

[英]How to implement f (g x) (h x) point-freely in Haskell?

這個答案中,我們將學習如何在Haskell中無意義地實現函數\\xyz -> fx (gyz) ,其中fg是函數。 我的問題是

如何在Haskell中以無點方式編寫函數\\x -> f (gx) (hx) f g h是定義f (gx) (hx)的函數。

我目前想到的想法如下。

uncurry f (mapTuple ($ x) (g, h))

但是,幾次嘗試表明這是錯誤的。 甚至零件map ($ x) [g, h]也可疑:如果gh具有不同的范圍怎么辦?

另外,可讀性在這里不是太大的問題。

真誠的感謝您的幫助。

箭頭版本為

uncurry f . (g &&& h)

要么

(g &&& h) >>> uncurry f

如圖所示:

        g ────
       ╱          ╲
──── &&&      >>>  uncurry f ───
       ╲          ╱
        h ──── 

正如melpomene建議的那樣, \\x -> f (gx) (hx)等同於liftM2 fgh

如果您對如何將Haskell代碼轉換為無點Haskell代碼有疑問,可以嘗試Pointfree.io

它是一個很棒的工具,通常會告訴您何時不使用無點代碼,因為有時它會變得完全不可讀:-)

在此處輸入圖片說明

適用風格

f <$> g <*> h

控制組成

join ((g ~> h ~> id) f)

數據功能合並

join (f $* g $$ h *$ id)

數據功能默認

lurryA @N1 (f <$> (g <$> _1) <*> (h <$> _1))
lurryA @N4 (_1 <*> (_2 <*> _4) <*> (_3 <*> _4)) f g h

這僅用於收集和整理評論中的答案。 根據@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM