use*_*370 15 monads haskell category-theory
我想我会尝试耐人寻味的可表示的,仿函数包定义Monad
和Comonad
实例给出的函子data Pair a = Pair a a
是由表示的Bool
; 正如我之前关于矢量monad的问题的答案中提到的那样.
我注意到的第一件事情是让我的类型的实例Representable
,我不仅要界定tabulate
和index
,同时也保证了我喜欢的类型是的一个实例Indexable
,Distributive
,Keyed
,Apply
,Applicative
,和Functor
类型类.好了,好了,index
完成的定义Indexable
和<.>
功能Apply
可以使用<*>
从Applicative
; 并且Functor
实例是必需的并不奇怪.不过,我对我的怀疑实例Keyed
和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 <$> 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
.
正如我通过定义Monad
和Comonad
实例所得出的那样,我发现Bool
需要Semigroup
定义Extend
和Monoid
定义Comonad
.我跟随Semigroup
的情况下Either
,这是同构的(||)
,并选择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
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
为所有其他超类提供定义.
这些Extend
和Comonad
定义实际上并不是要求的一部分Representable
.他们虽然包括在内,因为要表示的意思,你是同构的功能,使您能够回收的"指数"的定义Comonad
(又名cowriter,或追述 comonad)成为一个Comonad
为好,给你的一些代表性半群.但这不是必需的,主要是因为我不能在给定的类型的情况下限制它.
您可能要下降了Semigroup
,并Monoid
为Bool
虽然,只是手器extend
和extract
.这很容易.
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个半群可用.