Haskell 哪种语言扩展支持编写;A类(B类和c类)=>;D c在哪里?“?这个类型类声明的含义是什么?

Haskell 哪种语言扩展支持编写;A类(B类和c类)=>;D c在哪里?“?这个类型类声明的含义是什么?,haskell,ghc,typeclass,frp,type-families,Haskell,Ghc,Typeclass,Frp,Type Families,我试图理解以下类声明: class (MonadHold t (PushM t), MonadSample t (PullM t), Functor (Event t), Functor (Behavior t)) => Reflex t where data Behavior t :: * -> * 在FRP图书馆里 1)哪些语言扩展使编写函子(行为t)=>反射t成为可能?我猜这是语言扩展的组合。我猜这涉及到类型族,但还有什么 换句话说,我必须打开什么语言扩展,这样一个包含c

我试图理解以下类声明:

class (MonadHold t (PushM t), MonadSample t (PullM t), Functor (Event t), Functor (Behavior t)) => Reflex t where
  data Behavior t :: * -> *
在FRP图书馆里

1)哪些语言扩展使编写
函子(行为t)=>反射t
成为可能?我猜这是语言扩展的组合。我猜这涉及到类型族,但还有什么

换句话说,我必须打开什么语言扩展,这样一个包含
class a(bc)=>dc的代码才能编译

2)
A类(B c)=>D c的含义是什么,其中…

3)你能给出一个超级简单的例子来解释为什么和什么时候要写
class a(bc)=>dc,其中…

4)在哪里描述了什么
A类(B c)=>D c,其中…
是什么意思?我猜有一篇SPJ的论文或谈话描述了它,你能指一下吗

编辑:

其他相关信息:

上面写着:

在Haskell 98中,类声明的上下文(它引入 超类)必须简单;也就是说,每个谓词必须由 应用于类型变量的类


如果我正确解释了上述引文,那么在Haskell 98中,只允许
class A b=>cb,其中
shaped class声明是允许的,这意味着
class A(bc)=>dc
是不允许的。所以问题是,如果后者被允许,而前者不被允许,那么谁和什么定义了后者的含义?后者不是正确的Haskell 98语法,因此它的含义也没有在任何Haskell 98书中描述,那么它是后者的含义在哪里描述/记录/指定的?

首先,正如您正确猜测的那样,
行为
是一种,因此属于
类型族
扩展

类函子(行为t)=>reflect,其中数据行为t::*->*
的要点是强制要求,对于任何类型
t
,它是
reflect
的实例,无论您定义为关联数据类型
行为t
的数据类型是什么,您还必须将该类型设置为
Functor
的实例

下面是一个小示例:假设我使用这个类定义:

{-# LANGUAGE TypeFamilies, FlexibleContexts #-}

class Functor (F a) => Funky a where
    data F a :: * -> *
这允许写一些类似的东西

frobulate :: (Funky a) => F a Int -> F a Bool
frobulate = fmap (< 5)
因为关联的数据类型
F Int
不是
Functor
的实例:

No instance for (Functor (F Int))
  arising from the superclasses of an instance declaration
In the instance declaration for `Funky Int'
这迫使您也添加一个实例定义,如

instance Functor (F Int) where
    fmap f (MkF x) = MkF (f x)

请注意,后一个
函子
实例也需要启用
FlexibleInstances

以下是我对答案的理解。我花了一段时间才理解它,所以我把它写下来,也许这对其他人有帮助

传统的类型类声明(Haskell 98)
class(Eq a)=>MyClass a,其中
表示如果
a
MyClass
的实例,那么
a
必须是
Eq
的实例,左侧
Eq a
(意思是
a
Eq
的实例)如果右侧为true,则必须为true的谓词
MyClass a
(意味着
a
MyClass
的实例)

因此,换句话说,类声明类似于
class($Predicate)=>MyClass classInstance
,其中
$Predicate
可以是例如
Eq a
,这意味着
a
Eq
的实例

但是,如果启用
FlexibleContexts
语言扩展,那么谓词可能会比只启用
ATypeClass-typeParameter
更复杂

它可以是
ATypeClass SomeComplexType
,这意味着-通过概括Haskell 98的规则,
SomeComplexType
ATypeClass
的一个实例

哈斯凯尔报告(如丹尼尔的回答所述)中暗含了这一概括过程

以下三个简短的程序演示了这一概括规则。第一个编译第二个不编译,第三个再次编译

第二个无法编译,因为
气味
不是
StringLike
,这是
IntLike
的类声明所要求的。但是,如果我们删除该约束(在第三个程序中),那么程序将再次编译

下面是一个玩具示例,它编译:

{-# LANGUAGE FlexibleContexts #-}


class StringLike a where
 getString :: a->String

class (StringLike Smells) =>IntLike a where
 getInt :: a-> Int

instance IntLike Colors where
  getInt x = 0

instance StringLike Colors where
 getString x = "Hello"

instance StringLike Smells where
 getString x = "Bad"

data Colors = Blue | Red
data Smells = Rose | Trash
但是,以下操作失败:

{-# LANGUAGE FlexibleContexts #-}


class StringLike a where
 getString :: a->String

class (StringLike Smells) =>IntLike a where
 getInt :: a-> Int

instance IntLike Colors where
  getInt x = 0

instance StringLike Colors where
 getString x = "Hello"


data Colors = Blue | Red
data Smells = Rose | Trash
出现以下错误消息:

test.hs:10:10:
    No instance for (StringLike Smells)
      arising from the superclasses of an instance declaration
    In the instance declaration for `IntLike Colors'
Failed, modules loaded: none.
但是,以下代码再次编译得很好:

{-# LANGUAGE FlexibleContexts #-}


class StringLike a where
 getString :: a->String

class (StringLike Smells) =>IntLike a where
 getInt :: a-> Int


instance StringLike Colors where
 getString x = "Hello"


data Colors = Blue | Red
data Smells = Rose | Trash

第4部分:哈斯克尔报告:

假设实例类型
(tu1…uk)
中的类型变量满足实例上下文
cx′
中的约束。在此假设下,还必须满足以下两个条件:

  • 必须满足
    C
    的超类上下文
    cx[(tu1…uk)/u]
    表示的约束。换句话说,
    T
    必须是
    C
    的每个超类的实例,所有超类实例的上下文必须由
    cx′
    隐含
  • 对于实例类型中的类型变量的任何约束,如果要使
    d
    中的类方法声明类型良好,则必须满足这些约束

  • 这些讨论都没有假设超类上下文是报告中其他地方要求的简化形式;因此可以(并且确实)作为更复杂的超类上下文的含义。

    非常感谢,这里定义了“类函子的点(行为t)”吗=>反射t,其中数据行为t::*->*强制要求,对于作为反射实例的任何类型t,无论定义为关联数据类型行为t的数据类型是什么,都必须将该类型转换为Functor实例。“?你怎么知道的?哪篇SPJ论文对此进行了描述?更多
    {-# LANGUAGE FlexibleContexts #-}
    
    
    class StringLike a where
     getString :: a->String
    
    class (StringLike Smells) =>IntLike a where
     getInt :: a-> Int
    
    
    instance StringLike Colors where
     getString x = "Hello"
    
    
    data Colors = Blue | Red
    data Smells = Rose | Trash