【问题标题】:Haskell kinds. Beginner哈斯克尔种类。初学者
【发布时间】:2017-12-21 22:51:36
【问题描述】:

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 有两种具体类型作为参数(StringInt)。 g 有一个参数 (Bool) 这两个都是 T 的参数。所以我有:(*->*->*)->(*->*)->*。 它是否正确?谢谢

【问题讨论】:

  • 在 GHCi 中,:info C 会告诉你f 的类型,:kind T 会告诉你T 的类型。
  • @ReinHenrichs 我怀疑这是作业。打算用有机大脑来推理。
  • fcomp 的名字绝对是赠品。
  • 仅供参考,C 类只是来自 semigroupoids 包的 Semigroupoid

标签: haskell functional-programming data-kinds


【解决方案1】:

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

data T f g = T (f String Int) (g Bool)

在文件Kinds.hs 中,您可以将其加载到GHCi 并询问T 的类型:

> :l Kinds.hs
> :k T
T :: (* -> * -> *) -> (* -> *) -> *
>

所以看起来 GHCi 同意您的解决方案。

对于你的第一个问题,你不能让GHCi直接告诉你f的种类,但是由于f是类型类C的参数,你可以问C的种类:

> :k C
C :: (* -> * -> *) -> Constraint
>

意味着C 采用* -> * -> * 的类型来产生约束。所以,GHCi 不同意你的观点,认为f 是善良的* -> * -> *

查看类型签名:

comp :: f b c -> f a b -> f a c

请注意,您不能拥有 f(* -> *) -> * -> *,因为 f b c 会暗示 b 是同类 * -> *,而 f a b 会暗示 b 是同类 * ,而且不能两者兼有。

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

f :: k -> k -> *

前两个参数被强制使用相同类型k,因为b 在两个位置都使用(分别在f a bf b c),最终结果强制使用类型@987654348 @ 因为 f b cf a bf a c 都需要是具体类型才能使 comp 的类型签名有意义。

但是,Haskell98(无扩展)不会推断出最一般的可能种类,因此它选择 k*,并给出种类签名 * -> * -> *。事实证明,如果你启用了某个扩展(PolyKinds),那么kind签名将改为k -> k -> *

【讨论】:

    【解决方案2】:

    对于第一个问题,我不明白您为什么认为a 具有善意的* -> *。从所写的内容来看,a 只是一个*,仅此而已。所以f的种类就是* -> * -> *

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多