繁体   English   中英

Applicative 接口是否提供了超越将多参数函数(以柯里化形式)提升到 Functor 的能力?

[英]Does the Applicative interface provide power beyond the ability to lift multi-argument functions (in curried form) into a Functor?

应用程序通常作为一种将多参数函数提升为函子并将函子值应用于它的方式呈现。 但我想知道是否有一些微妙的额外功能源于它可以通过提升返回 function 的函数并一次应用 function arguments 来实现这一点。

想象一下,我们定义一个基于提升函数的接口,其参数是 arguments 的元组:

# from Functor
fmap :: (a -> b) -> Fa -> Fb
# from Applicative
pure :: a -> Fa

# combine multiple functor values into a functor of a tuple
tuple1 :: Fa -> F(a)
tuple2 :: Fa -> Fb -> F(a,b)
tuple3 :: Fa -> Fb -> Fc -> F(a,b,c)
(etc ...)

# lift multi-argument functions (that take a tuple as input)
ap_tuple1 :: ((a) -> b) -> F(a) -> Fb
ap_tuple2 :: ((a,b) -> c) -> F(a,b) -> Fc
ap_tuple3 :: ((a,b,c) -> d) -> F(a,b,c) -> Fd
(etc ..)

假设我们为我们可能遇到的每个大小的元组定义了相应的元组 function。 考虑到它允许提升/应用于多参数函数但不允许提升/应用于返回 function 的函数,该接口是否与 Applicative 接口一样强大? 显然,可以对以元组作为参数的函数进行 curry,以便可以在应用程序中提升它们,并且可以对返回 function 的函数进行 uncurry,以便将它们提升到上面的假设实现中。 但在我看来,权力有细微的差别。 有什么区别吗? (假设这个问题甚至是有道理的)

您重新发现了Applicative幺半群表示 它看起来像这样:

class Functor f => Monoidal f where
    (>*<) :: f a -> f b -> f (a, b)
    unit :: f ()

它通过以下方式与Applicative同构:

(>*<) = liftA2 (,)
unit = pure ()

pure x = x <$ unit
f <*> x = fmap (uncurry ($)) (f >*< x)

顺便说一句,您的ap_tuple函数都只是fmap 具有多个值的“硬”部分是将它们组合在一起。 将它们拆分回碎片“很容易”。

是的,这同样强大。 注意puretuple1是一样的。 此外,高于tuple2的所有内容都从tuple2fmap中恢复:

tuple3 x y z = repair <$> tuple2 (tuple2 x y) z
    where repair ((a, b), c) = (a, b, c)
tuple4 w x y z = repair <$> tuple2 (tuple2 x y) (tuple2 x y)
    where repair ((a, b), (c, d)) = (a, b, c, d)
-- etc.

此外,所有ap_tuple都只是fmap

ap_tuple1 = fmap
ap_tuple2 = fmap
ap_tuple3 = fmap
-- ...

重命名prod = tuple2 ,你的问题归结为

class Functor f => Applicative f where pure:: a -> fa prod:: fa -> fb -> f (a, b)

相当于

class Functor f => Applicative f where pure:: a -> fa liftA2:: (a -> b -> c) -> fa -> fb -> f c

?

您可能已经看到答案是肯定的。 prod只是liftA2的专业化

prod = liftA2 (,)

但是(,)是“自然的”,因为它不会“删除”任何内容,因此您可以通过解构数据来恢复liftA2

liftA2 f x y = f' <$> prod x y
    where f' (a, b) = f a b

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM