可表示的Functor同形(Bool - > a)

use*_*370 15 monads haskell category-theory

我想我会尝试耐人寻味的可表示的,仿函数包定义MonadComonad实例给出的函子data Pair a = Pair a a是由表示的Bool; 正如我之前关于矢量monad的问题的答案中提到的那样.

我注意到的第一件事情是让我的类型的实例Representable,我不仅要界定tabulateindex,同时也保证了我喜欢的类型是的一个实例Indexable,Distributive,Keyed,Apply,Applicative,和Functor类型类.好了,好了,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)
Run Code Online (Sandbox Code Playgroud)

我的mapWithKey定义借鉴了[]实例的定义Keyed:虽然我不明白为什么0每次迭代都使用它.我有类似的用于False每个术语Pair.

正如我通过定义MonadComonad实例所得出的那样,我发现Bool需要Semigroup定义ExtendMonoid定义Comonad.我跟随Semigroup的情况下Either,这是同构的(||),并选择Falsemempty:

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
Run Code Online (Sandbox Code Playgroud)

那么,我Representable是否正确地满足了课程的要求?

Edw*_*ETT 15

是的,你有.虽然您的实例Keyed已关闭.

instance Keyed Pair where
    mapWithKey f (Pair x y) = Pair (f False x) (f True y)
Run Code Online (Sandbox Code Playgroud)

甚至更容易

instance Keyed Pair where
    mapWithKey = mapWithKeyRep
Run Code Online (Sandbox Code Playgroud)

和类似的

instance Distributive Pair where
    distribute = distributeRep
Run Code Online (Sandbox Code Playgroud)

给定index并且tabulate您可以使用模块中的各种fooRep方法Representable为所有其他超类提供定义.

这些ExtendComonad定义实际上并不是要求的一部分Representable.他们虽然包括在内,因为要表示的意思,你是同构的功能,使您能够回收的"指数"的定义Comonad(又名cowriter,或追述 comonad)成为一个Comonad为好,给你的一些代表性半群.但这不是必需的,主要是因为我不能在给定的类型的情况下限制它.

您可能要下降了Semigroup,并MonoidBool虽然,只是手器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
Run Code Online (Sandbox Code Playgroud)

此外,这种类型被提供表示的-尝试包,其中包括许多其他实例.

和,

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 <$> 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 ]
Run Code Online (Sandbox Code Playgroud)

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

  • 两者都有效.你只需要关联性和论证的单位.选择是任意的.如果没有任何意义,那么你完全有权完全放弃comonad. (2认同)