理解`种类``随机`

时间:2015-01-23 03:33:11

标签: haskell

Maybe,我理解为type constructor,有* -> *种。据我所知,它需要一种类型才能生成一种类型。

ghci> :k Maybe
Maybe :: * -> *
ghci> :k Maybe Int
Maybe Int :: *

但是,以下输出意味着什么?

ghci> :k Random
Random :: * -> Constraint

1 个答案:

答案 0 :(得分:7)

Haskell中有几种。具体类型具有种类*,这意味着它已完全应用,因此Int[String]IO (Maybe Int)等类型。然后有些类型采用* -> k形式,其中k是一种类型变量。这些就像Haskell中的函数一样,它带有一个或多个参数,除了* 具有是一个具体的类型,它不是变量。例子是

> :kind Maybe
Maybe :: * -> *
> :kind Either
Either :: * -> * -> *
> data Foo a b c d e = Foo
> :kind Foo
Foo :: * -> * -> * -> * -> * -> *

然后有一种Constraint,它由一个或多个 1 构成:

> :kind Num
Num :: * -> Constraint
> :kind Show
Show :: * -> Constraint
> import Control.Monad.State
> :kind MonadState
MonadState :: * -> (* -> *) -> Constriant

最后一个有点复杂,但是把它想象成一个更高阶的函数,其中(* -> *)意味着第二个参数必须是一个类型构造函数,其中有一个类型参数。

Random只是一个简单的类型类,因此需要一个完全应用的类型并生成Constraint

还有原始类型#,类型的值是原始的并且被烘焙到GHC中,它们甚至需要语言扩展来解析它们的名称:

> import GHC.Prim
> :set -XMagicHash
> :i Int#
data Int#
> :k Int#
Int# :: #

大多数Haskell程序员都不需要使用它们,但如果您需要为GHC API进行低级编程,它们就可用。

通过几个扩展程序,您甚至可以自己制作

> :set -XDataKinds
> :set -XKindSignatures
> :set -XGADTs
> -- Multiline input in GHCi
> :set +m
> data FlagType = Flag1 | Flag2 deriving (Show)
> data Foo :: FlagType -> * -> *
|     F1 :: Int -> Foo 'Flag1 Int
|     F2 :: String -> Foo 'Flag2 String
|
> :t F1 1
F1 1 :: Foo 'Flag1 Int
> :t F2 "foo"
F2 "foo" :: Foo 'Flag2 String

Kinds给我们提供了一种类型级编程的形式,有很多技巧可以用来构建漂亮的API。

1。 Not necessarily true