2016-07-23 62 views
1

this answer得知如何在Haskell中以毫無意義的方式實現函數\x y z -> f x (g y z),其中fg是函數。我的問題是如何在Haskell中自由地實現f(g x)(h x)?

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

我現在想到的想法如下所示。

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

但是有幾次嘗試表明這是錯誤的;即使部分map ($ x) [g, h]是可疑的:如果gh有不同的範圍?

此外,可讀性在這裏不是太多的問題。

任何幫助,真誠讚賞。

+1

這只是'liftA2 f g h'。 – melpomene

+0

感謝您的建議。但我對頭痛了解「APPlicative」是什麼。也許有些其他的方式,而不是'Applicative'?還是謝謝。 :) – awllower

+4

當然:'liftM2 f g h' :-) – melpomene

回答

3

由於melpomene建議,\x -> f (g x) (h x)相當於liftM2 f g h

當您有關於如何將Haskell代碼轉換爲無點Haskell代碼的問題時,您可以試試Pointfree.io

這是一個偉大的工具,它往往可以告訴你何時不使用pointfree代碼,因爲它會完全不可讀有時:-)

enter image description here

+0

感謝您的答案和這個有趣的網站。 :) – awllower

+2

更好地使用'liftA2'而不是'liftM2',後者自AMP以來已被棄用。 – leftaroundabout

+0

你也可以使用'pointfree'命令行實用程序(也可以編寫綁定將它集成到ghci會話中):https://hackage.haskell.org/package/pointfree –

6

arrow版本將

uncurry f . (g &&& h) 

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

作爲圖:

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

感謝您的代碼。現在我將嘗試學習一些箭頭。 :) – awllower

2

應用型式

f <$> g <*> h 

Control.Compose

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

Data.Function.Meld

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

Data.Function.Tacit

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

經過很長時間,我終於得到了這段代碼所說的:'f <$> g <*> h'。我認爲這不是別的,而是'ap(f。g)h'。無論如何,感謝這些有用的信息。 – awllower

+1

@awllower檢查了我在這裏發佈的「直覺」http://stackoverflow.com/a/34536499/260584,它提供了一種直觀的方式來思考應用程序的功能。還要注意'<$>'是'.','<*>'是Lambda微積分組合器S,'pure'是組合器K(它是'const')。 – erisco

0

這隻用於收集和整理評論中的答案。 據@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的作用是由apK通過const。因此,我們可以寫

ap (ap (const f) g) h 

事實上,我們可以進一步降低:

ap (const f) g = f . g 

所以我們的函數可以寫爲:

ap (f . g) h 

如果翻譯成應用型風格,我們得到:

f <$> g <*> h 

然後,這種系統的方法可以應用於所有的lambda術語,並提供無點式的風格。 :)

相關問題