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