haskell - Haskell 中伴随函子的函数依赖
问题描述
在 Haskell 中很容易描述附加:
class Functor f where
map :: (a -> b) -> f a -> f b
class Functor m => Monad m where
return :: a -> m a
join :: m (m a) -> m a
class Functor w => Comonad w where
extract :: w a -> a
duplicate :: w a -> w (w a)
class (Comonad w, Monad m) => Adjoint w m | w -> m, m -> w where
unit :: a -> m (w a)
counit :: w (m a) -> a
但是,我很难证明这一点StoreT s w
并且StateT s m
是伴随的。
instance Adjoint w m => Adjoint (StoreT s w) (StateT s m) where
-- ...
GHC 抱怨m
无法确定,StoreT s w
因为m
没有出现在StoreT s w
:
• Illegal instance declaration for
‘Adjoint (StoreT s w) (StateT s m)’
The coverage condition fails in class ‘Adjoint’
for functional dependency: ‘w -> m’
Reason: lhs type ‘StoreT s w’
does not determine rhs type ‘StateT s m’
Un-determined variable: m
Using UndecidableInstances might help
• In the instance declaration for
‘Adjoint (StoreT s w) (StateT s m)’
我真的不明白为什么这是一个问题,w -> m
因为Adjoint w m
. GHC 进一步建议开启-XUndecidableInstances
. 在这种情况下这样做是否安全?我在尝试做一些不可能的事情吗?
解决方案
您的实例以您描述的方式被拒绝,因为它不遵循类的功能依赖项的覆盖条件。正如在为什么此实例无法满足覆盖条件的答案中所讨论的那样?,Adjoint w m
在检查覆盖条件时不考虑对您的实例的约束。
GHC 进一步建议开启
-XUndecidableInstances
. 在这种情况下这样做是否安全?
UndecidableInstances
是一个相对无害的扩展。打开它时可能发生的最糟糕的事情是构建失败,因为某些实例使类型检查器循环。虽然 GHC 在这件事上默认是保守的,但有时您比编译器更清楚,并且可以确定实例解析将终止。在这种情况下,打开UndecidableInstances
就可以了。特别是,在这里做这件事似乎很好。
旁注:我在您的代码中看到的一个问题是,StoreT s w
实际上StateT s m
并不是伴随的。特别是,右伴随词必须是可表示的,并且StateT s m
是不可表示的。即使我们设法编写了类型检查的实现unit
,counit
它们实际上也不会产生附加同构。另请参阅如何在Data.Functor.Adjunction
.
推荐阅读
- bash - 在 Windows 上的 mobaxterm 上使用完整路径时,命令 mkdir -p 返回:“mkdir:无法创建目录'/drives/f/':权限被拒绝”
- bash - 使用 Groovy 脚本列出具有活动选择的分支
- python - 如何在 Ubuntu 上的 LibreOffice 中打开 xlsx 文件?
- angular - 处理 Angular 材料反应形式错误消息的最佳方法是什么?
- unity3d - Unity 中有什么方法可以在内置管道中使用 HDRP 制作贴花投影仪之类的东西吗?
- php - Laravel Nova 条件验证:required_if + 存在规则
- linux - 如何向 docker 容器添加 SSH 访问权限
- java - 如何在具有@ManyToMany关系JPA springboot的同时摆脱循环冗余
- javascript - 在 javascript 或 c# 中从 Html 源中查找重定向 URL
- unity3d - Unity - 如何根据 3D 中另一个对象的间距计算一个对象的新位置