- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这里是 MonadState
的定义,但问题适用于具有 FunctionalDependencies
的任何此类:
class Monad m => MonadState s m | m -> s where
...
假设我有一个使用 s
作为类型参数的数据类型和一个与之一起工作的类型类:
data StateType s = StateType
class MonadState s m => FunDeps s m a where
workWithStateType :: a -> StateType s -> m ()
我可以愉快地为这个类创建一个按预期编译和工作的实例:
instance (MonadIO m, MonadState s m) => FunDeps s m (IORef (StateType s)) where
workWithStateType ref a = liftIO $ writeIORef ref a
但我觉得 FunDeps
类中的 s
是多余的,我可以这样定义一个类:
class FunDepsProblem m a where
workWithStateTypeNoCompile :: MonadState s m => a -> StateType s -> m ()
instance (MonadIO m, MonadState s m) => FunDepsProblem m (IORef (StateType s)) where
...
问题是当我尝试实现它时:
instance (MonadIO m, MonadState s m) => FunDepsProblem m (IORef (StateType s)) where
workWithStateTypeNoCompile ref a = liftIO $ writeIORef ref a
我收到一个编译错误,告诉我它无法统一实例头和函数中的状态标记 s
:
fun-deps.hs:18:62: error: …
• Couldn't match type ‘s1’ with ‘s’
‘s1’ is a rigid type variable bound by
the type signature for:
workWithStateTypeNoCompile :: forall s1.
MonadState s1 m =>
IORef (StateType s) -> StateType s1 -> m ()
at /path/to/fun-deps.hs:18:3-28
‘s’ is a rigid type variable bound by
the instance declaration
at /path/to/fun-deps.hs:17:10-78
Expected type: StateType s
Actual type: StateType s1
• In the second argument of ‘writeIORef’, namely ‘a’
In the second argument of ‘($)’, namely ‘writeIORef ref a’
In the expression: liftIO $ writeIORef ref a
• Relevant bindings include
a :: StateType s1
(bound at /path/to/fun-deps.hs:18:34)
ref :: IORef (StateType s)
(bound at /path/to/fun-deps.hs:18:30)
workWithStateTypeNoCompile :: IORef (StateType s)
-> StateType s1 -> m ()
(bound at /path/to/fun-deps.hs:18:3)
|
Compilation failed.
我知道当它以这种形式定义时,那里有一个隐式的forall
:
workWithStateTypeNoCompile :: forall s m a . MonadState s m => a -> StateType s -> m ()
所以从技术上讲,它应该适用于每个 s
,并且在没有 FunctionalDependencies
的情况下它完全有意义,但是 s
是已知的 m
是已知的,所以这是我没有得到的部分。
换句话说,monad m
在类头和函数中统一为相同的,因此它应该在实例中唯一标识状态类型 s
头和功能类型。所以我的问题是为什么它没有被统一?这是否有理论上的原因,或者它根本没有在 ghc 中实现?
事实上,如果我将 MonadState
重写为概念上相同的功能,但使用 TypeFamilies
而不是 FunctionalDependencies
问题似乎就消失了:
class Monad m => MonadStateFamily m where
type StateToken m :: *
class Family m a where
familyStateType :: MonadStateFamily m => a -> StateType (StateToken m) -> m ()
instance (MonadIO m, MonadStateFamily m, s ~ StateToken m) => Family m (IORef (StateType s)) where
familyStateType ref a = liftIO $ writeIORef ref a
最佳答案
显然这是 FunctionalDependencies
的已知限制。我挖了一个 Haskell 咖啡馆 message by Manuel Chakravarty十多年前提到 FunctionalDependencies
不适用于存在类型,并提供了一个非常简洁明了的示例:
class F a r | a -> r
instance F Bool Int
data T a = forall b. F a b => MkT b
add :: T Bool -> T Bool -> T Bool
add (MkT x) (MkT y) = MkT (x + y)
上面的示例会产生编译器错误,表明它无法统一唯一标识的类型,本质上是问题的标题。
• Couldn't match expected type ‘b’ with actual type ‘b1’
‘b1’ is a rigid type variable bound by
a pattern with constructor: MkT :: forall a b. F a b => b -> T a,
in an equation for ‘add’
这是问题的编译错误,看起来与上面的非常相似。
• Couldn't match type ‘s1’ with ‘s’
‘s1’ is a rigid type variable bound by
the type signature for:
workWithStateTypeNoCompile :: forall s1.
MonadState s1 m =>
IORef (StateType s) -> StateType s1 -> m ()
我怀疑这里使用的是完全相同的概念,因为 workWithStateTypeNoCompile
上的 forall
,类型变量 s1
错误是存在的。
在任何情况下都不会丢失所有内容,而且对于我遇到的问题有一个不错的解决方法。特别是从类实例头中移除 s
是必要的,这可以通过 newtype
来实现:
class FunDepsWorks m a where
workWithStateTypeCompile :: MonadState s m => a s -> StateType s -> m ()
newtype StateTypeRef s = StateTypeRef (IORef (StateType s))
instance MonadIO m => FunDepsWorks m StateTypeRef where
workWithStateTypeCompile (StateTypeRef ref) a = liftIO $ writeIORef ref a
请注意,a
现在是元数为 1 的类型变量,并应用于 s
。
感谢 Ben Gamari 的编译 tf vs fd wiki 页面,否则我永远不会找到具有存在类型的示例。
关于haskell - FunctionalDependencies 不统一唯一标识的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61179896/
我正在为期末考试学习,但我无法理解这个 FC 算法: 我理解你标准化每条规则的部分。然后我认为下一行是说对于满足广义 Modus Ponens (p'_iTheta = p_iTheta) 的每个 t
我有一个 3d 世界,它有一个 simpel 平台和一个代表玩家的立方体。当我旋转平台时,立方体会滑动并按照您预期的方式执行,增加和减少物理 Material 中的摩擦力。 我希望立方体在输入例如 f
所以我的 Unity 项目有一个大问题。我昨天工作,我没有做备份今天,在我打开项目后,我的笔记本电脑因电池电量不足而关机。之后,当我进入项目时,我得到了这个:加载“Assets/MyScene.uni
好的,我正在尝试创建一个函数来确定元组列表是否是可传递的,即如果 (x,y) 和 (y,z) 在列表中,那么 (x,z) 也在列表中。 例如,[(1,2), (2,3), (1,3)]是传递的。 现在
这个问题在这里已经有了答案: How to pass data between scenes in Unity (5 个回答) 9 个月前关闭。 我有一个游戏,我有一个队列匹配系统。 我想向玩家展示他
我现在正在为我的游戏创建一个 keystore (统一)但是当我按下添加键按钮时,会弹出一个错误 Java Development Kit (JDK) directory is not set or
我想将YouTube流视频放入Cardboard(适用于Android和iOS)应用中。我知道这些插件可以执行类似的操作,例如“Easy Movie Texture”,但它们不支持YouTube流媒体
我需要限制 ConfigurableJoint 的目标旋转以避免关节变形或破坏。 为了了解角度限制的工作原理,我做了一个实验。 在场景中放置一个人形模型。 为骨骼添加ConfigurableJoint
尝试实现一种有限形式的匹配统一。 尝试匹配两个公式匹配如果我们能找到替代出现在公式中的变量使得两者在句法上是等价。 我需要写一个函数来判断一个对应于基本项的常数,例如 Brother(George)
我正在使用 Unity 和 C#我想在运行时将输出日志文件发送到我的电子邮件,我使用了来自 this question 的 ByteSheep 答案和来自 this question 的 Arkane
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我希望能够将鼠标悬停在游戏对象(代理)上并在右键或左键单击时创建一个类似于 Windows 右键单击菜单的 float 菜单。我试过结合使用 OnGUI() 和 OnMouseOver() 但我要
我正在为 oculus Gear VR 开发游戏(考虑内存管理),我需要在特定时间(以秒为单位)后加载另一个屏幕 void Start () { StartCoroutine (loadSce
我设法生成了敌人,但它们一直在生成。如何设置限制,避免不断生成? 我已经尝试添加 spawnLimit 和 spawnCounter 但无法让它工作。 var playerHealth = 100;
我正在参加使用 Unity 进行游戏开发的在线类(class),讲师有时会含糊不清。我的印象是使用游戏对象与使用游戏对象名称(在本例中为 MusicPlayer)相同,但是当我尝试将 MusicPla
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 6 年前。 Improve this qu
为了好玩,我正在(用 Java)开发一个使用统一算法的应用程序。 我选择了我的统一算法返回所有可能的统一。例如,如果我尝试解决 添加(X,Y)=成功(成功(0)) 返回 {X = succ(succ(
如何让对象在一段时间后不可见(或只是删除)?使用 NGUI。 我的示例(更改): public class scriptFlashingPressStart : MonoBehaviour {
我有下一个错误: The type or namespace name 'NUnit' could not be found (are you missing a using directive or
这是可以做到的 但是属性 autoSizeTextType 只能用于 API LEVEL >= 26,并且 Android Studio 会显示有关该问题的烦人警告。 为了摆脱这个问题,我想以编程方
我是一名优秀的程序员,十分优秀!