Haskell 哈斯克尔种类。新手

Haskell 哈斯克尔种类。新手,haskell,functional-programming,data-kinds,Haskell,Functional Programming,Data Kinds,什么是f class C f where comp :: f b c -> f a b -> f a c 我写过:(*->*)->*->*->* 这是正确的吗c是一种具体类型*a是一种接受类型并生成类型的类型。这两个参数都是f?我的论点正确吗 什么是T data T f g = T (f String Int) (g Bool) f有两种具体类型作为参数(String和Int)g有一个参数(Bool),这两个参数都是T的参数。所以我有:(*->*->*->*)->(*->

什么是
f

class C f where
    comp :: f b c -> f a b -> f a c
我写过:
(*->*)->*->*->*
这是正确的吗
c
是一种具体类型
*
a
是一种接受类型并生成类型的类型。这两个参数都是
f
?我的论点正确吗

什么是
T

data T f g = T (f String Int) (g Bool)
f
有两种具体类型作为参数(
String
Int
g
有一个参数(
Bool
),这两个参数都是
T
的参数。所以我有:
(*->*->*->*)->(*->*)->*

这是正确的吗?谢谢你的第一个问题,我不明白你为什么决定
a
有种类
*->*
。从所写的内容来看,
a
只是一个
*
,仅此而已。因此,
f
的类型是
*->*->*


对于第二个问题,你是对的。

对于第一个问题,我不明白你为什么决定
a
有种类
*->*
。从所写的内容来看,
a
只是一个
*
,仅此而已。因此,
f
的类型是
*->*->*


对于第二个问题,你是对的。

GHCi可以告诉你各种各样的事情。例如,如果您将:

data T f g = T (f String Int) (g Bool)
在文件
types.hs
中,您可以将其加载到GHCi中,并请求类型为
T

> :l Kinds.hs
> :k T
T :: (* -> * -> *) -> (* -> *) -> *
>
看来GHCi同意你的解决方案

对于第一个问题,您不能要求GHCi直接告诉您
f
的种类,但由于
f
是typeclass
C
的一个参数,因此您可以要求提供
C
的种类:

> :k C
C :: (* -> * -> *) -> Constraint
>
这意味着
C
采用一种类型
*->*->*
来生成约束。因此,GHCi不同意您的观点,认为
f
属于
*->*->*->*

查看以下项的类型签名:

comp :: f b c -> f a b -> f a c
请注意,您不能拥有
f
类型的
(*->*)->*->*->*
,因为
fbc
意味着
b
属于
*->*
类型,而
fab
意味着
b
属于
*
类型,并且不能两者兼而有之

事实证明,最普遍的可能类型是:

f :: k -> k -> *
其中,由于在两个位置(分别在
fab
fbc
中)都使用了
b
,因此前两个参数被强制具有相同的
k
,并且最终结果被强制具有kind
*
,因为
fbc
fab
,和
fac
都需要是具体的类型,才能使
comp
的类型签名有意义


但是,Haskell 98(无扩展)不能推断出最普遍的可能种类,因此它选择
k
作为
*
,给出种类签名
*->*->*
。事实证明,如果您启用某个扩展(
PolyKinds
),那么种类签名将改为
k->k->*

GHCi可以告诉您各种类型的东西。例如,如果您将:

data T f g = T (f String Int) (g Bool)
在文件
types.hs
中,您可以将其加载到GHCi中,并请求类型为
T

> :l Kinds.hs
> :k T
T :: (* -> * -> *) -> (* -> *) -> *
>
看来GHCi同意你的解决方案

对于第一个问题,您不能要求GHCi直接告诉您
f
的种类,但由于
f
是typeclass
C
的一个参数,因此您可以要求提供
C
的种类:

> :k C
C :: (* -> * -> *) -> Constraint
>
这意味着
C
采用一种类型
*->*->*
来生成约束。因此,GHCi不同意您的观点,认为
f
属于
*->*->*->*

查看以下项的类型签名:

comp :: f b c -> f a b -> f a c
请注意,您不能拥有
f
类型的
(*->*)->*->*->*
,因为
fbc
意味着
b
属于
*->*
类型,而
fab
意味着
b
属于
*
类型,并且不能两者兼而有之

事实证明,最普遍的可能类型是:

f :: k -> k -> *
其中,由于在两个位置(分别在
fab
fbc
中)都使用了
b
,因此前两个参数被强制具有相同的
k
,并且最终结果被强制具有kind
*
,因为
fbc
fab
,和
fac
都需要是具体的类型,才能使
comp
的类型签名有意义


但是,Haskell 98(无扩展)不能推断出最普遍的可能种类,因此它选择
k
作为
*
,给出种类签名
*->*->*
。事实证明,如果您启用某个扩展(
PolyKinds
),那么种类签名将改为
k->k->*

在GHCi中,
:info C
将告诉您
f
的种类,
:kind T
将告诉您
T
的种类。我怀疑这是家庭作业。用于用有机大脑进行推理。名称
f
comp
是绝对的赠品。仅供参考,类
C
只是
Semigroupoid
包中的
Semigroupoid
。在GHCi中,
:info C
会告诉你
f
的种类,
:kind T
会告诉你
T
的种类我怀疑这是家庭作业。用于用有机大脑推理。名称
f
comp
是绝对的赠品。仅供参考,类
C
只是
半群体
来自
半群体
包。