应用仿函数作为monoidal函子 [英] Applicative functors as monoidal functors

查看:158
本文介绍了应用仿函数作为monoidal函子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如Hackage所述, Applicative Functors

a>,它们是强力松散monoidal函子。那么为什么他们在Haskell中的定义没有如下所示:

  class Functor f => MonoidalApplicative f其中
mult :: f a - > f b - > f(a,b)
unit :: a - > f a

starAp :: f(a - > b) - > f a - > fb
starAp hx = fmap(uncurry($))(mult hx)

< *>< / code>(starAp)在乘法方面很容易重建,这个定义对我来说更简单。举例来说,下面是Maybe实例:

pre $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ = Just(x,y)
mult _ _ = Nothing

unit x = Just x

$ b $ C $ C>>> = 。当有几种语义上相同的方法来定义某些东西时,最好总是选择最高效的&务实的方式。 Haskell被设计为编写代码,而不是用来证明事情(不过,不幸的是,Haskell 不幸仍然变得非常流行的编程语言)。



如果 starAp 具有默认实现,几乎没有人会实现它(就像现在在>> 中发生的 Monad 类型类)。但是<> 是非常有用的操作。它用于应用程序& monadic解析器很多( megaparsec attoparsec optparse-appative ),我无法想象我的生活将不需要 liftA * 来加入。此操作尽可能高效非常重要。将> starAp 实现为 fmap(uncurry($))(mult hx)可能会给内联和优化带来困难编译器。

此外,使用 mult 应用 code> unit 操作并不能真正解决任何问题。显然, mult = liftA2(,)。但是,您的实现方式是使用

mult(Just x)(Just y)= Just(x,y)



不完全正确。因为你的实现不够懒惰。你会评估两种情况,当它可能足以评估一个。所以你甚至可以用这个简单的功能搞定。因此这种表示方式严重恶化。

As mentioned in Hackage for Applicative Functors, they are strong lax monoidal functors. So why doesn't their definition in Haskell show it like so :

class Functor f => MonoidalApplicative f where
  mult :: f a -> f b -> f (a,b)
  unit :: a -> f a 

  starAp :: f (a -> b) -> f a -> f b
  starAp h x = fmap (uncurry ($)) (mult h x)

<*> (starAp) is easily reconstructed in terms of the multiplication and this definition looks simpler to me. For exemple, here is the Maybe instance :

instance MonoidalApplicative Maybe where
  mult (Just x) (Just y) = Just (x,y)
  mult _ _ = Nothing

  unit x = Just x

解决方案

As it was mentioned in comments to your answer, there is similar story with join and >>=. When there're several semantically equivalent ways to define something it's better always to choose most efficient & pragmatic way. Haskell was designed to write code, not to prove things (though, somehow Haskell haven't still become very popular programming language unfortunately).

If starAp had default implementation almost nobody would implement it (just as it happens now with >> in Monad type class). But <*> is extremely useful operation. It is used in applicate & monadic parsers a lot (megaparsec, attoparsec, optparse-applicative) and I can't imagine my life w/o liftA* for joining things. And it is very important for this operation to be as efficient as possible. Implementing starAp as fmap (uncurry ($)) (mult h x) may bring hard times to inlining and optimizing things for compiler.

Moreover, representation of Applicative using mult and unit operations doesn't really solves any problems. Obviously, mult = liftA2 (,). But your implementation with

mult (Just x) (Just y) = Just (x,y)

not fully correct. Because your implementation is not lazy enough. You will evaluate both cases when it may be enough to evaluate only one. So you still can fuck up even with this simple function. Thus this representation is strictly worse.

这篇关于应用仿函数作为monoidal函子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆