在围绕objective包玩游戏时,我注意到以下类型具有有趣的属性。
> {-# LANGUAGE RankNTypes #-}
> data N f r = N { unN :: forall x. f x -> (x, r) }
这是一个Functor。
> instance Functor (N f) where
> fmap f (N nat) = N $ fmap (fmap f) nat
> -- or, = N $ \fx -> let { (x,a) = nat fx } in (x, f a)
经过几个小时的google / hoogle,我放弃了发现任何事情 包含此类型的现有模块。 这是什么类型?如果众所周知,名称是什么?这有用还是被忽略,因为没用?
这不是我100%的原始创作,因为N源自目标包中的Object。
> data Object f g = Object {
> runObject :: forall x. f x -> g (x, Object f g)
> }
N f
是一个Functor,当应用Fix时会生成Object f Identity
。
以下是关于此类型的事实以及为什么我认为它很有趣。
N将Reader转换为Writer,反之亦然。 (这里我用(=)符号表示类型之间的同构)
N ((->) e) r
= forall x. (e -> x) -> (x, r)
= (e, r)
N ((,) d) r
= forall x. (d, x) -> (x, r)
= d -> r
N将Store comonad转换为State monad,但inverse不为真。
> data Store s a = Store s (s -> a)
> type State s a = s -> (s, a)
N (Store s) r
= forall x. (s, (s -> x)) -> (x, r)
= forall x. s -> (s -> x) -> (x, r)
= s -> (s, r)
= State s r
N (State s) r
= forall x. (s -> (s, x)) -> (x, r)
= forall x. (s -> s, s -> x) -> (x, r)
= forall x. (s -> s) -> (s -> x) -> (x, r)
= (s -> s) -> (s, r) -- ???
N不能采取可能。
N Maybe r
= forall x. Maybe x -> (x, r)
= forall x. (() -> (x, r), x -> (x, r))
= Void -- because (() -> (x, r)) can't be implemented
以下功能可能很有趣。我无法做到这一点。
> data Cofree f a = Cofree a (f (Cofree f a))
> data Free f a = Pure a | Wrap (f (Free f a))
> unfree :: Free (N f) r -> N (Cofree f) r
> unfree (Pure r) = N $ \(Cofree a _) -> (a, r)
> unfree (Wrap n_f) = N $
> \(Cofree _ f) -> let (cofree', free') = unN n_f f
> in unN (unfree free') cofree'
整篇文章都是有文化的Haskell(.lhs)。
答案 0 :(得分:2)
我称之为"处理程序"仿函数。在我发布目标之前,曾经使用处理程序仿函数定义Object
。
是的,这个仿函数很有趣 - Cofree (Handler f)
有一个公共吸气者,Free (Handler f)
是mortal object。也许我应该运送处理程序函子......
答案 1 :(得分:1)
虽然已经回答了,但我自己找到了问题的另一个答案。
类型N
是类型类Pairing
的值级表示形式,在以下文章中有所描述。
Free for DSLs, cofree for interpreters
Cofree Comonads and the Expression Problem (Paring在这里称为Dual)
N
是相同的事情Pairing的定义是这样的。
> class Pairing f g where
> pair :: (a -> b -> c) -> f a -> g b -> c
f
和N f
正在配对。
> instance Pairing f (N f) where
> pair k fa nb = uncurry k $ unN nb fa
N
可以用配对来表示。
> data Counterpart f r = forall g. Pairing f g => Counterpart (g r)
>
> iso1 :: N f r -> Counterpart f r
> iso1 = Counterpart
>
> iso2 :: Counterpart f r -> N f r
> iso2 (Counterpart gr) = N $ \fx -> pair (,) fx gr
有一个Free-vs-Cofree实例,对应于我的unfree
。
其他有趣的实例也在文章中定义。
> instance Pairing f g => Pairing (Free f) (Cofree g) where
> pair = undefined -- see link above
前篇文章goes to扩展配对以在Monad m中进行计算。
> class PairingM f g m | f -> g, g -> f where
> pairM :: (a -> b -> m r) -> f a -> g b -> m r
如果我们将PairingM重写为类似于N的形式,我们会再次获得Object。
> -- Monad m => HandlerM' f m r ~ HandlerM f m r
> data HandlerM' f m r = forall g. PairingM f g m => HandlerM' (g r)
> data HandlerM f m r = HandleM { runHandlerM :: forall x. f x -> m (x, r) }
>
> -- Fix (HandlerM f m) ~ Object f m
> -- Free (HandlerM f m) ~ (mortal Object from f to m)