什么是Ord类型?

时间:2015-07-23 21:37:42

标签: haskell

每个类都不是Haskell中的类型:

Prelude> :t max
max :: Ord a => a -> a -> a
Prelude> :t Ord

<interactive>:1:1: Not in scope: data constructor ‘Ord’
Prelude> 

为什么这不会打印Ord类型签名?

4 个答案:

答案 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一样。它们仍然不是类型,因为永远不会有任何值将它们作为类型,因此您不能在函数中使用OrdOrd 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)

Prelude> :k Ord Ord :: * -> Constraint 不是类型,而是typeclass。它没有类型,但是

{{1}}

类型类是Haskell的精彩之处。检查出来: - )

答案 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中唯一可以以大写字母开头的函数。