kqr*_*kqr 15
这是,使用所谓的适用风格,
h <$> f <*> g
Run Code Online (Sandbox Code Playgroud)
使用<$>和<*>来自Control.Applicative.
另一种方法是用一个升级h到(->) rapplicative functor
liftA2 h f g
Run Code Online (Sandbox Code Playgroud)
这背后的直觉是,如果
h :: a -> b -> c
-- then --
liftA2 h :: (r -> a) -> (r -> b) -> r -> c
Run Code Online (Sandbox Code Playgroud)
因此,提升版本需要两个函数r -> something而不是实际的somethings,然后提供一个r以从something函数中获取s.
该liftA*和的相应组合<$>和<*>是相等的.
J. *_*son 12
虽然@kqr具有基于Applicative实例的更实用的解决方案((->) a),但我们也可以在"管道"方法中讨论它
+----- f ------+
/ \
<---- h +------< x
\ /
+----- g ------+
Run Code Online (Sandbox Code Playgroud)
它提供了一种非常有组织的无点程序.我们将使用来自的工具创建此程序Control.Arrow.
首先,我们得在Haskell使用一个共同的缺失功能我们图中最右边的部分称为diag或dup
--+
\
+----- x dup :: x -> (x, x)
/ dup x = (x, x)
--+
Run Code Online (Sandbox Code Playgroud)
然后使用(***)组合器创建中间Control.Arrow
----- f ----- (***) :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
f :: (a -> b)
g :: (c -> d)
----- g ----- f *** g :: (a, c) -> (b, d)
Run Code Online (Sandbox Code Playgroud)
然后左侧正是我们uncurry所做的
+-- uncurry :: (a -> b -> c) -> (a, b) -> c
/ h :: (a -> b -> c)
h uncurry h :: (a, b) -> c
\
+--
Run Code Online (Sandbox Code Playgroud)
然后将它们连接在一起我们可以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 ----+
Run Code Online (Sandbox Code Playgroud)