可表示函子同构于 (Bool -> a)

发布于 2024-11-10 15:27:03 字数 2388 浏览 2 评论 0 原文

我想我会尝试有趣的 Representable-functors 包为给定的函子定义 MonadComonad 实例data Pair a = Pair a a,用Bool表示;正如我之前关于向量 monad 的问题的回答中提到的。

我注意到的第一件事是,为了使我的类型成为可表示的实例,我不仅应该定义制表符和索引,还应该确保我的类型是 IndexableDistributiveKeyedApplyApplicative 的实例,和函子类型类。好了,好了,index就完成了Indexable的定义,Apply<.>函数就可以了使用Applicative中的<*>;需要一个 Functor 实例也就不足为奇了。尽管如此,我对 KeyedDistributive 的实例表示怀疑。

data Pair a = Pair a a
  deriving (Show,Eq)

instance Functor Pair where
  fmap f (Pair x y) = Pair (f x) (f y)

type instance Key Pair = Bool

instance Keyed Pair where
  mapWithKey f (Pair x y) = Pair (f False x) (f False y)

instance Indexable Pair where
  index (Pair x _) False = x
  index (Pair _ y) True  = y

instance Applicative Pair where
  pure a = Pair a a
  Pair f g <*> Pair x y = Pair (f x) (g y)

instance Apply Pair where
  (<.>) = (<*>)

instance Distributive Pair where
  collect f x = Pair (getL . f <$> x) (getR . f <$> x)
    where getL (Pair x _) = x
          getR (Pair _ y) = y

instance Representable Pair where
  tabulate f = Pair (f False) (f True)

我的 mapWithKey 定义借用了 Keyed[] 实例的定义:尽管我不明白为什么 0每次迭代都使用它。我对 Pair 的每个术语都使用了类似的 False

当我通过定义 MonadComonad 实例得出结论时,我发现 Bool 需要 Semigroup 定义 >Extend,以及 ComonadMonoid 定义。我遵循 EitherSemigroup 实例,它与 (||) 同构,并为 False 选择mempty

instance Monad Pair where
  return = pureRep
  (>>=)  = bindRep

instance Monoid Bool where
  mempty = False
  mappend = (||)

instance Semigroup Bool where
  (<>) = mappend

instance Extend Pair where
  extend = extendRep -- needs Bool Semigroup

instance Comonad Pair where
  extract = extractRep -- needs Bool Monoid

那么,我是否正确、惯用地满足了 Representable 类的要求?

I thought I'd try the intriguing Representable-functors package to define a Monad and Comonad instance for the functor given by data Pair a = Pair a a which is representable by Bool; as mentioned in the answer to my earlier question on the vector monad.

The first thing I noticed was that to make my type an instance of Representable, I should not only define tabulate and index, but also ensure my type is an instance of the Indexable, Distributive, Keyed, Apply, Applicative, and Functor type classes. Well, ok, index completes the definition of Indexable, and the <.> function of Apply can use <*> from Applicative; and it shouldn't be a surprise that a Functor instance is required. Nevertheless, I am doubtful of my instances for Keyed and Distributive.

data Pair a = Pair a a
  deriving (Show,Eq)

instance Functor Pair where
  fmap f (Pair x y) = Pair (f x) (f y)

type instance Key Pair = Bool

instance Keyed Pair where
  mapWithKey f (Pair x y) = Pair (f False x) (f False y)

instance Indexable Pair where
  index (Pair x _) False = x
  index (Pair _ y) True  = y

instance Applicative Pair where
  pure a = Pair a a
  Pair f g <*> Pair x y = Pair (f x) (g y)

instance Apply Pair where
  (<.>) = (<*>)

instance Distributive Pair where
  collect f x = Pair (getL . f <
gt; x) (getR . f <
gt; x)
    where getL (Pair x _) = x
          getR (Pair _ y) = y

instance Representable Pair where
  tabulate f = Pair (f False) (f True)

My mapWithKey definition borrows from that of the [] instance for Keyed: though I don't understand why 0 was used there for every iteration. I have similarly used False for each term of Pair.

As I concluded by defining the Monad and Comonad instances, I discovered that Bool requires a Semigroup definition for Extend, and a Monoid definition for Comonad. I follow the Semigroup instance for the Either, which is isomorphic to (||), and choose False for mempty:

instance Monad Pair where
  return = pureRep
  (>>=)  = bindRep

instance Monoid Bool where
  mempty = False
  mappend = (||)

instance Semigroup Bool where
  (<>) = mappend

instance Extend Pair where
  extend = extendRep -- needs Bool Semigroup

instance Comonad Pair where
  extract = extractRep -- needs Bool Monoid

So then, have I met the requirements of the Representable class correctly, and idiomatically?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羁拥 2024-11-17 15:27:03

是的,你有。尽管您的 Keyed 实例已关闭。

instance Keyed Pair where
    mapWithKey f (Pair x y) = Pair (f False x) (f True y)

或者甚至更简单

instance Keyed Pair where
    mapWithKey = mapWithKeyRep

,类似

instance Distributive Pair where
    distribute = distributeRep

给定 indextabulate,您可以使用 Representable 模块中的各种 fooRep 方法来提供所有其他超类的定义。

ExtendComonad 定义实际上并不是可表示 要求的一部分。不过它们也被包含在内,因为可表示意味着您与函数同构,这使您能够重复使用“指数”Comonad(又名 cowriter,或 追踪 comonad) 也成为一个 Comonad ,只要你的表示有一些幺半群。但这不是必需的,主要是因为我无法将其限制为所涉及的类型。

您可能想删除 BoolSemigroupMonoid,而只需手动实现 extendextract 。这很容易。

instance Extend Pair where
    extend f p@(Pair a b) = Pair (f p) (f (Pair b a))

instance Comonad Pair where
    extract (Pair a b) = a

另外,此类型是 rel="noreferrer">representable-tries 包,其中包含许多其他实例。

并且,

import Control.Applicative
bool = [True, False]
f tt _tf _ft _ff True  True  = tt
f _tt tf _ft _ff True  False = tf
f _tt _tf ft _ff False True  = ft
f _tt _tf _ft ff False False = ff
associative f = and (assoc <
gt; bool <*> bool <*> bool) where 
    assoc a b c = f (f a b) c == f a (f b c)
semigroups = filter associative 
    [ f tt tf ft ff | tt <- bool, tf <- bool, ft <- bool, ff <- bool ]
unital (u, f) = all unit bool where 
    unit a = f u a == a && f a u == a
monoids = filter unital 
    [ (u, f) | u <- bool, f <- semigroups ]

表明正如您猜测的那样,有 4 个可能的幺半群,如果您只想要一个扩展实例,则有 8 个半群可用。

Yes you have. Though your instance for Keyed is off.

instance Keyed Pair where
    mapWithKey f (Pair x y) = Pair (f False x) (f True y)

or even easier

instance Keyed Pair where
    mapWithKey = mapWithKeyRep

and similarly

instance Distributive Pair where
    distribute = distributeRep

Given index and tabulate you can use the various fooRep methods in the Representable module to provide definitions for all of the other superclasses.

The Extend and Comonad definitions, are not actually part of the requirements to be Representable. They are included though, because being representable means you are isomorphic to a function, which enables you to recycle the definition for the "exponential" Comonad (aka cowriter, or Traced comonad) to become a Comonad as well, given some monoid on your representation. This isn't required though, mainly because I can't constrain it to hold given the types involved.

You may want to drop the Semigroup and Monoid for Bool though and just hand implement extend and extract. It is easy enough.

instance Extend Pair where
    extend f p@(Pair a b) = Pair (f p) (f (Pair b a))

instance Comonad Pair where
    extract (Pair a b) = a

Also, this type is provided by the representable-tries package, which includes a number of other instances.

And,

import Control.Applicative
bool = [True, False]
f tt _tf _ft _ff True  True  = tt
f _tt tf _ft _ff True  False = tf
f _tt _tf ft _ff False True  = ft
f _tt _tf _ft ff False False = ff
associative f = and (assoc <
gt; bool <*> bool <*> bool) where 
    assoc a b c = f (f a b) c == f a (f b c)
semigroups = filter associative 
    [ f tt tf ft ff | tt <- bool, tf <- bool, ft <- bool, ff <- bool ]
unital (u, f) = all unit bool where 
    unit a = f u a == a && f a u == a
monoids = filter unital 
    [ (u, f) | u <- bool, f <- semigroups ]

shows that as you surmised there are the 4 possible monoids you surmised and if you only want an extend instance, there are 8 semigroups available.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文