首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以为这种类型创建一个应用实例吗?

可以为这种类型创建一个应用实例吗?
EN

Stack Overflow用户
提问于 2022-07-09 00:23:57
回答 1查看 121关注 0票数 3

为了探索方差是如何工作的,我提出了这种类型,它可以是Functor,也可以是Contravariant,具体取决于它的参数:

代码语言:javascript
复制
newtype Shift f g a = Shift { runShift :: f a -> g a }

它类似于Endo,除非有额外的类型变量来使类型的方差变得模糊。

如果f是协变的,而g是反变的,那么Shift f g是相反的:

代码语言:javascript
复制
instance (Functor f, Contravariant g) => Contravariant (Shift f g) where
    contramap f (Shift g) = Shift (contramap f . g . fmap f)

如果f是反变的,而g是协变的,那么Shift f g是协变的:

代码语言:javascript
复制
instance (Contravariant f, Functor g) => Functor (Shift f g) where
    fmap f (Shift g) = Shift (fmap f . g . contramap f)

我的理解是,Divisible (从Data.Functor.Contravariant.Divisiblecontravariant包)是ContravariantApplicativeFunctor。使用它,Shift也可以扩展为Divisible的一个实例:

代码语言:javascript
复制
instance (Functor f, Divisible g) => Divisible (Shift f g) where
    conquer = Shift (const conquer)
    divide f (Shift g) (Shift h) = Shift $
        \x -> case unzipF (fmap f x) of
            (b,c) -> divide f (g b) (h c)
unzipF :: Functor f => f (a,b) -> (f a,f b)
unzipF x = (fmap fst x, fmap snd x)

因为对Divisible (Shift f g)的约束是(Functor f, Divisible g),所以对于Applicative实例,我期望它相应地“翻转”。

代码语言:javascript
复制
instance (Contravariant f, Applicative g) => Applicative (Shift f g) where { ... }

然而,我不知道如何填写细节。我未完成的实现需要这样一个函数:

代码语言:javascript
复制
unzipC :: Contravariant f => f (a,b) -> (f a,f b)

但我想不出不使用fmap的解决方案。

以下是完整的实现:

代码语言:javascript
复制
instance (Contravariant f, Applicative g) => Applicative (Shift f g) where
    pure x = Shift (const (pure x))
    liftA2 f (Shift g) (Shift h) = Shift $
        \x -> case unzipC (contramap (uncurry f) x) of
            (a,b) -> liftA2 f (g a) (h b)

那么,这样的unzipC甚至存在吗?如果没有,是否仍有可能挽救Applicative (Shift f g)实例?

EN

回答 1

Stack Overflow用户

发布于 2022-07-09 00:54:31

不,这样的(总)函数不可能存在。注意,它将允许您构造一个类型为Void的值。

代码语言:javascript
复制
import Data.Functor.Contravariant
import Data.Void

unzipC :: Contravariant f => f (a,b) -> (f a,f b)
unzipC = undefined

uhoh :: Void
uhoh = getOp (fst $ unzipC $ Op snd) ()

我不确定是否还有其他方法来编写您想要的实例。如果我搞清楚了,我会编辑这个答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72918092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档