在特定情况下的功能依赖性

乔什·柯克林(Josh Kirklin)

作为介绍,请参阅此问题我的答案最后,我注意到您似乎可以消除对具有功能依赖性的无关类型规范的需要。现在的代码如下:

{-# LANGUAGE GADTs, MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies #-}

data Nil
data TList a b where
    TEmpty :: TList Nil Nil
    (:.) :: c -> TList d e -> TList c (TList d e)
infixr 4 :.

class TApplies f h t r where
    tApply :: f -> TList h t -> r

instance TApplies a Nil Nil a where
    tApply a _ = a

instance TApplies f h t r => TApplies (a -> f) a (TList h t) r where
    tApply f (e :. l) = tApply (f e) l]

现在,对我而言,直观的事情似乎是将Fundep添加f h t -> r TApplies类型类中。但是,当我这样做时,GHC抱怨TApplies如下的递归实例

Illegal instance declaration for
‘TApplies (a -> f) a (TList h t) r’
The coverage condition fails in class ‘TApplies’
   for functional dependency: ‘f h t -> r’
Reason: lhs types ‘a -> f’, ‘a’, ‘TList h t’
   do not jointly determine rhs type ‘r’

最后两行对我来说似乎是错误的,尽管我希望我只是误解了一些东西。我的推理如下:

  1. 如果我们有a -> fand a,那么我们就拥有f
  2. 如果我们有,TList h t那么我们有ht
  3. 既然有了TApplies f h t r,我们就有了资金f h t -> r
  4. 因此,因为我们有fh而且t,我们有r

在我看来,这意味着功能依赖性已得到满足有人可以指出我逻辑上的缺陷,也许还建议对功能依赖性进行更适当的选择?(请注意,f r -> hGHC允许类似的操作,但似乎在类型指示方面没有太多余地。)

用户名

首先,我不知道为什么要使用如此复杂的数据类型-因此,我将使用简化的数据类型来解决您的问题。但是,相同的原理也适用于您的确切情况。

将数据类型定义为:

data TList (xs :: [*]) where 
  Nil :: TList '[]
  (:.) :: x -> TList xs -> TList (x ': xs) 

infixr 4 :.

然后您的班级少了一个类型参数:

class TApplies f (xs :: [*]) r | f xs -> r where ...

有问题的实例看起来像

instance TApplies g ys q => TApplies (y -> g) (y ': ys) q where 

现在,检查产生的错误(与您的问题基本相同)-即,请注意,它说“覆盖条件在类'TApplies'中失败”。那么什么是“覆盖条件”?用户指南有这样一段话:

覆盖条件。对于类的每个函数依赖项tvsleft-> tvsright,S(tvsright)中的每个类型变量都必须出现在S(tvsleft)中,其中S是将类声明中的每个类型变量映射到实例中对应类型的替换宣言。

这过于技术性,但是从根本上说,这是右侧的类型变量集-在这种情况下,即{q}必须是左侧的变量集的子集-这里{y, g, ys}显然不是这样。

您会注意到覆盖条件没有说明实例的上下文。这是您问题的根源!在确定功能依赖项是否成立时,考虑上下文我想您会同意我的看法,即该实例显然失败了instance TApplies (y -> g) (y ': ys) q where ...,这是编译器看到的。

解决方案很简单:添加{-# LANGUAGE UndecidableInstances #-}到文件顶部。除其他外,覆盖条件的目的是确保实例解析终止。如果启用UndecidableInstances,则表示“信任我,它将终止”。


附带说明一下,当前的公式使用起来不是很好。例如,tApply (+) (1 :. 2 :. Nil)产生“歧义类型”错误或类似的错误。更糟糕的是,tApply (+) (1 :. "s" :. Nil)会产生相同的确切“歧义类型”错误!对于任何尝试使用此类编写代码的人来说都没有太大帮助。您必须在各处指定单态类型签名,以使其按原样工作。

解决方案是使实例声明符合以下条件:

instance (a ~ a') => TApplies a '[] a' where
instance (TApplies g ys q, y ~ y') => TApplies (y -> g) (y' ': ys) q where 

然后,第一种情况按原样编译,键入defaulting插入,并显示“ 3”。在第二种情况下,您得到No instance for (Num [Char]),这实际上是有帮助的。

再次起作用的原因是,实例解析仅关心实例头,而不关心上下文。instance TApplies (y -> g) (y' ': ys) q是编译器所看到的,显然yy'可以是任意的,无关的,种类。只是到最后,当需要打印值时,编译器才需要解析y ~ y'约束,此时您只需拥有表达式(+) 1 2


您可以按以下方式实现没有数据种类的类型:

{-# LANGUAGE GADTs #-}
data Cons a b 
data Nil

data TList xs where
  Nil  :: TList Nil
  (:.) :: x -> TList xs -> TList (Cons x xs)

但是,没有真正的理由这样做,因为DataKinds不会破坏其他有效的代码。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在不公开其异步依赖性的情况下将功能类型公开为业务需求?

来自分类Dev

特定情况下的时序图

来自分类Dev

在特定情况下替换字符

来自分类Dev

特定情况下的开关盒

来自分类Dev

特定情况下的分段错误

来自分类Dev

opencv的某些功能在某些特定情况下显示错误

来自分类Dev

opencv的某些功能在某些特定情况下显示错误

来自分类Dev

Python-仅在不满足依赖性的情况下才需要安装Pip

来自分类Dev

可选的线程安全性(仅在特定情况下具有线程安全性部分)

来自分类Dev

在特定情况下未调用Firebase onDataChange

来自分类Dev

在特定情况下显示和隐藏弹出窗口

来自分类Dev

在特定情况下未绘制视图

来自分类Dev

在特定情况下如何抑制声纳法则?

来自分类Dev

在特定情况下使用控件结构显示表单

来自分类Dev

在特定情况下显示和隐藏弹出窗口

来自分类Dev

NodeJS在特定情况下使用错误

来自分类Dev

在特定情况下如何使用高阶结构

来自分类Dev

选择器在特定情况下的独占CSS

来自分类Dev

在特定情况下未绘制视图

来自分类Dev

如何在特定情况下捕获OnTouchEvent?

来自分类Dev

在特定情况下如何抑制声纳法则?

来自分类Dev

在特定情况下,如何使JRadioButton透明?

来自分类Dev

在sql server中的特定情况下除以零

来自分类Dev

在条件不起作用的情况下使用输出变量的Azure DevOps阶段到阶段依赖性

来自分类Dev

由于不兼容的依赖性(在安装EclipseFP的情况下),在ubuntu 14.04上进行cabal install scion-browser失败

来自分类Dev

jQuery-ui自动完成功能仅在特定情况下不起作用

来自分类Dev

C ++ std :: vector在特定情况下的行为就像泄漏内存

来自分类Dev

为什么在这种特定情况下扫描仪输入显示错误?

来自分类Dev

在特定情况下用破折号替换新行

Related 相关文章

  1. 1

    如何在不公开其异步依赖性的情况下将功能类型公开为业务需求?

  2. 2

    特定情况下的时序图

  3. 3

    在特定情况下替换字符

  4. 4

    特定情况下的开关盒

  5. 5

    特定情况下的分段错误

  6. 6

    opencv的某些功能在某些特定情况下显示错误

  7. 7

    opencv的某些功能在某些特定情况下显示错误

  8. 8

    Python-仅在不满足依赖性的情况下才需要安装Pip

  9. 9

    可选的线程安全性(仅在特定情况下具有线程安全性部分)

  10. 10

    在特定情况下未调用Firebase onDataChange

  11. 11

    在特定情况下显示和隐藏弹出窗口

  12. 12

    在特定情况下未绘制视图

  13. 13

    在特定情况下如何抑制声纳法则?

  14. 14

    在特定情况下使用控件结构显示表单

  15. 15

    在特定情况下显示和隐藏弹出窗口

  16. 16

    NodeJS在特定情况下使用错误

  17. 17

    在特定情况下如何使用高阶结构

  18. 18

    选择器在特定情况下的独占CSS

  19. 19

    在特定情况下未绘制视图

  20. 20

    如何在特定情况下捕获OnTouchEvent?

  21. 21

    在特定情况下如何抑制声纳法则?

  22. 22

    在特定情况下,如何使JRadioButton透明?

  23. 23

    在sql server中的特定情况下除以零

  24. 24

    在条件不起作用的情况下使用输出变量的Azure DevOps阶段到阶段依赖性

  25. 25

    由于不兼容的依赖性(在安装EclipseFP的情况下),在ubuntu 14.04上进行cabal install scion-browser失败

  26. 26

    jQuery-ui自动完成功能仅在特定情况下不起作用

  27. 27

    C ++ std :: vector在特定情况下的行为就像泄漏内存

  28. 28

    为什么在这种特定情况下扫描仪输入显示错误?

  29. 29

    在特定情况下用破折号替换新行

热门标签

归档