每个类都不是Haskell中的类型:
Prelude> :t max
max :: Ord a => a -> a -> a
Prelude> :t Ord
<interactive>:1:1: Not in scope: data constructor ‘Ord’
Prelude>
为什么这不会打印Ord
类型签名?
答案 0 :(得分:10)
好的,这里有几件事情。
首先,当您撰写:t Ord
时,您正在值命名空间中寻找名为Ord
的内容;特别是它必须是一个构造函数,因为名称以大写字母开头。
Haskell使类型和值完全分开;类型名称与类型构造函数名称之间没有关系。通常,当只有一个构造函数时,人们将使用与该类型相同的名称。一个例子是data Foo = Foo Int
。这声明了两个新的命名实体:类型Foo
和构造函数Foo :: Int -> Foo
。
将它视为只是创建一个类型Foo
并且可以在类型表达式中使用以及构造Foo
s并不是一个好主意。因为data Maybe a = Nothing | Just a
之类的声明也很常见。这里有Maybe a
的2个不同构造函数,而Maybe
在值级别上根本不是任何名称。
因为您在类型表达式中看到Ord
并不意味着在值级别有一个名称Ord
,您可以询问:t
的类型。即使有,也不一定与类型级名称Ord
相关。
需要澄清的第二点是,不,类实际上不是类型。类是 set 类型(它们都支持类中定义的接口),但它本身不是类型。
在vanilla Haskell中,类型只是“额外”的东西。您可以使用class
声明声明它们,使用instance
声明对它们进行实例化,并使用附加到类型的特殊语法(=>
箭头左侧的内容)作为约束类型变量。但它们并不真正与语言的其他部分交互,你不能在类型签名的主要部分使用它们(`=&gt;箭头的右边)。
但是,如果启用了ConstraintKinds
扩展名,则类型类 do 将成为类型名称空间中存在的普通内容,就像Maybe
一样。它们仍然不是类型,因为永远不会有任何值将它们作为类型,因此您不能在函数中使用Ord
或Ord Int
作为参数或返回类型,或者一个[Ord a]
或类似的东西。
因为它们有点像Maybe
这样的类型构造函数。 Maybe
是类型命名空间中绑定的名称,但它不是类型;没有类型仅为Maybe
的值,但Maybe
可用作定义类型的表达式的部分,如Maybe Int
。
如果您不熟悉种,可能会忽略我从ConstraintKinds
开始所说的一切;你最终可能会了解种类,但它们并不是你作为初学者需要了解多少的功能。但是,如果你是ConstraintKinds
做的是特殊类型Constraint
并且具有类型类约束(=>
箭头的左侧),那么只是普通的类型级别的事物{{{ 1}}而不是特殊目的语法。这意味着Constraint
是一个类型级别的东西,我们可以用GHCI中的Ord
命令来表达它的类型:
:k
哪个有意义; Prelude> :k Ord
* -> Constraint
类型为max
,因此Ord a => a -> a -> a
必须有Ord a
种类。如果Constraint
可以应用于普通类型以产生约束,则它必须具有类型Ord
。
答案 1 :(得分:8)
Ord
不属于某种类型;它是一个类型类。类型类允许您将支持的操作与给定类型相关联(有点类似于Java中的接口或Objective-C中的协议)。一种类型(例如Int
)是&#34;实例&#34;类型类(例如Ord
)意味着该类型支持Ord
类型类的功能(例如compare
,<
,>
等。) / p>
您可以在ghci中使用:i
获取有关类型类的大部分信息,其中显示了与类型类关联的函数以及哪些类型是它的实例:
ghci > :i Ord
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(>=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(<=) :: a -> a -> Bool
max :: a -> a -> a
min :: a -> a -> a
-- Defined in ‘GHC.Classes’
instance Ord a => Ord (Maybe a) -- Defined in ‘Data.Maybe’
instance (Ord a, Ord b) => Ord (Either a b)
-- Defined in ‘Data.Either’
instance Ord Integer -- Defined in ‘integer-gmp:GHC.Integer.Type’
instance Ord a => Ord [a] -- Defined in ‘GHC.Classes’
...
答案 2 :(得分:2)
答案 3 :(得分:1)
不完全。您可以强加类型约束,因此Ord a
是一种类型,但Ord a => a
不是。 a
表示&#34;任何类型Ord
,其约束条件是:t
&#34;。
错误是因为Ord
需要表达式。当GHCi试图将using SP = Microsoft.SharePoint.Client;
SP.ClientContext SpContext = new SP.ClientContext("SITEURL");
SP.Web SiteWeb = SpContext.Web;
SP.List Lst = SpContext.Web.Lists.GetByTitle("LIST");
var ClientUserEffPerms = Lst.GetUserEffectivePermissions(@"<domain>\<username>");
SpContext.Load(SiteWeb, S => S.EffectiveBasePermissions);
SpContext.Load(Lst, L => L.EffectiveBasePermissions);
SpContext.ExecuteQuery();
解释为表达式时,它最接近的是数据构造函数,因为这些是Haskell中唯一可以以大写字母开头的函数。