gpt4 book ai didi

haskell - 在 Haskell 类型签名中列为约束变量?

转载 作者:行者123 更新时间:2023-12-04 14:31:49 24 4
gpt4 key购买 nike

而不是声明这个类型签名:

g :: Enum a => [a] -> [a]

我想使用这种风格:

h :: (Enum a, Functor f) => f a -> f a

除了将 Functor 换成 []。 (例如,因为我可能很高兴暂时在我的实现中不那么笼统)。

虽然我很想,但我不能使用下面的,

i :: (Enum a, [] f) => f a -> f a 
-- compilation error: Expected kind ‘* -> *’, but ‘f’ has kind ‘*’

因为 [] f 可能被解释为 f 的列表,而不是 f 被解释为 a 的约束变量一些东西的 list 。

以下是有效的,但我想知道是否可以将 List 声明为 Haskell 类型签名中的实际约束变量。

j :: (Enum a) => [] a -> [] a

最佳答案

[] 不是约束,也永远不会是。在 Haskell 中,每个类型都有一个 kind,这有点像类型的类型。这是一个级别。

[Int]StringDouble -> Double 都是具体类型。我们说他们有种类 Type。像 []Maybe 这样的东西有种类 Type -> Type;它接受一个类型作为参数,然后自己生成一个类型。

另一方面,像 Functor 这样的东西是根本不同的。 Functor 有种类

Functor :: (Type -> Type) -> Constraint

因此,首先,它采用参数化类型,如 []Maybe 作为参数。但即使它这样做了,它也会产生一个 Constraint,这是一个与 Type 根本不同的东西。现在,当我们写一个类型签名时

j :: (Enum a) => [] a -> [] a

=> 左边的东西是总是 约束,=> 右边的东西是始终 类型。将 [] a 放在 => 的左侧并不比将 Functor a 放在右侧更有意义-手边。

听起来您要表达的意思是“这个东西必须是一个列表”,在这种情况下,以下任一条件就足够了

j :: (Enum a) => [a] -> [a]
j :: (Enum a) => [] a -> [] a

两者是等价的,但前者更惯用。如果您稍后出现并决定“哦等等,我可以为任何仿函数做这个工作,您可以将类型签名更改为

j :: (Enum a, Functor f) => f a -> f a

这不会破坏调用 j 的任何代码,因为之前使用列表调用它的任何代码仍将使用有效的 Functor 调用它> 实例。


注意:您会看到一些涉及* 类型的旧文献。一些文献(甚至某些地方的 GHC)会说 Maybe 有种 * -> *。出于这些目的,* 等同于 Type。能够将 Type 称为 * 是一个不幸的历史怪癖,并且使 Haskell 解析器复杂化(Foo * Int 等同于 Foo Type Int 还是乘法像(*) Foo Int?),所以现在一般推荐使用Type来指代类型的种类。

关于haskell - 在 Haskell 类型签名中列为约束变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68092137/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com