Scala F[A]和A之间的区别是什么?
对于Scala和Haskell等语言,可以使用类型构造函数构造类型。区分所有这些部分的正确词汇是什么Scala F[A]和A之间的区别是什么?,scala,haskell,types,Scala,Haskell,Types,对于Scala和Haskell等语言,可以使用类型构造函数构造类型。区分所有这些部分的正确词汇是什么 A是一种类型F[A]也是一种类型。有没有语言可以区分这两者 什么是A 什么是F[A] 什么是F?在Scala中不知道,但在Haskell中,报告确实区分了两个语法类别:“类型”和“构造函数”。构造函数就是那些单原子类型,以大写字母开头,由data和newtype声明创建。e、 g data Foo a = Bar 创建一个新的类型构造函数Foo(和一个新的数据构造函数Bar),可以通过将Foo
A
是一种类型F[A]
也是一种类型。有没有语言可以区分这两者
什么是A
什么是F[A]
什么是
F
?在Scala中不知道,但在Haskell中,报告确实区分了两个语法类别:“类型”和“构造函数”。构造函数就是那些单原子类型,以大写字母开头,由data
和newtype
声明创建。e、 g
data Foo a = Bar
创建一个新的类型构造函数Foo
(和一个新的数据构造函数Bar
),可以通过将Foo
应用到另一个类型来形成类型。当然,建设者不必是更高级的data Baz=qux
还声明了名为Baz
的类型构造函数,该构造函数不允许应用于任何其他类型
(但请注意:通常使用“类型构造函数”来表示“任何带有箭头类型的类型级表达式”,因此,如果您正在进行一些技术写作,您应该在介绍中包含一些文本,以澄清您打算在本文档的其余部分中使用这两种含义中的哪一种。)
因此,在您的示例中,我们可以说Map
是一个构造函数,Char
是一个构造函数,Int
是一个构造函数,Map Char
是一个类型,Map Char Int
是一个类型
据我所知,这些类别中的任何一个都没有通用的速记词:“绝对不是构造函数的类型”、“绝对不是构造函数的类型”、“绝对不是构造函数的类型”。对于允许应用于另一种类型的类型,有术语“高级类型”——例如
Map
和Map Char
都是高级类型。注释中提到的技术术语是“类型”、“某些其他类型”和“类型构造函数”
考虑:
data A = A
-- ^ ^--- The Data Constructor
-- -- The type
data F x = SomeDataConstructorForF x
-- ^ ^ ^-- Data Constr ^-- Field
-- | --- Type Variable
-- - Type Constructor
val :: A
val = A
-- A value of type 'A'
val2 :: F [A]
val2 = SomeDataConstructorForF []
-- A value of some other type, F [A].
-- No special term exists for types built through application
-- of one or more type constructor afaik
我建议只调用
F[A]
类型构造函数的F[A]
应用程序F
类型的*->*
参数A
类型的
。来自规范,而“应用程序”来自基本的lambda演算,如下所述
回想当年的形式主义
这意味着您有以下形成种类的规则:
*
是一种a
,b
是种类,那么a->b
就是种类f
和a
是术语,则应用程序f a
是术语x
是一个变量名,y
是一个术语,那么抽象\x.y
就是一个术语k
(真空)的预定义常量c
具有类型k
,而与上下文无关Gamma
包含变量v
到种类k
的映射,那么在Gamma
中,我们可以推断v
是种类k
的一个良好的表达式Gamma
中,我们可以推断f
具有种类a->b
并且x
具有种类a
,那么应用程序fx
具有种类b
Gamma中,x:a
我们可以推断y
具有种类b
,那么在Gamma
中,我们可以推断\x.y
具有种类a->b
旁白:你实际上可以很快地写下以上基本的推理算法
sealed trait Term
case class Apply(func: Term, arg: Term) extends Term
case class Lam(preferred: String, dom: Type, body: Term) extends Term
case class BoundVar(deBruijnIdx: Int) extends Term
case class FreeVar(name: String) extends Term
sealed trait Type
case object * extends Type
case class Func(dom: Type, cod: Type) extends Type {
override def toString = s"($dom -> $cod)"
}
import util.{Either, Left, Right}
case class Ctx(globalConstants: Map[String, Type], stack: List[Type]) {
def push(tp: Type): Ctx = Ctx(globalConstants, tp :: stack)
def pop: Ctx = Ctx(globalConstants, stack.tail)
}
object Ctx {
def empty = Ctx(Map.empty, List.empty)
def emptyWithGlobals(keys: (String, Type)*) = Ctx(keys.toMap, Nil)
}
def tinf(t: Term, ctx: Ctx = Ctx.empty): Either[String, Type] = t match {
case FreeVar(v) =>
ctx.globalConstants.get(v).map(Right(_)).getOrElse(Left("Undefined: " + v))
case BoundVar(d) => Right(ctx.stack(d))
case Apply(f, x) =>
for {
tf <- tinf(f, ctx)
tx <- tinf(x, ctx)
res <- tf match {
case Func(a, b) =>
if (tx == a) Right(b)
else Left(s"Type mismatch: cannot apply `$a` to `$b`")
case sthElse => Left(s"Not applicable: $sthElse")
}
} yield res
case Lam(_, tp, b) =>
for {
tb <- tinf(b, ctx.push(tp))
} yield Func(tp, tb)
}
for {
example <- List(
Lam("x", *, BoundVar(0)),
Lam("x", *, Lam("y", Func(*, *), Apply(BoundVar(0), BoundVar(1))))
)
} println(example + " : " + tinf(example))
有那种
(* -> *)
(* -> ((* -> *) -> *))
分别。AFAIK对于
F[A]
没有明显的标准区别术语,因为它不是一个特别有用的区别A
和F[A]
是类型,F
是类型构造函数。我会借用函数中的术语。在F[A]
中,A
是参数,F[A]
可能是结果,F
是类型构造函数。有时候,它是上下文的,但是如果你举一个或两个例子,我可能会更有帮助。“不是所有类型的构造函数都是函子”。考虑两种类型的构造函数:代码> NeXType F f= f(f(f f))< /> >和<代码>数据nf a= z<a</c>。您认为更复杂的是:类型<代码> f nf<代码>还是类型<代码>整数< /代码>?(当然,这两种类型是不等价的,但它表明,您所讨论的复杂性与实现的关系比结果类型的任何基本属性都更密切。)@MarkCanlas5
是一个带值的表达式,5+2
也是一个带值的表达式;同样地,对于某些适当的函数f
。它们不需要特殊的名称来表示一个是函数调用的结果,一个是文本;它们只是价值观。同样,在类型级别,独立类型和通过将类型构造函数应用于某些类型参数而生成的类型是相同的,无论您如何生成它们。什么是“报告”?@MarkCanlas the Haskell Language Report,很容易用谷歌搜索:当你说Char
是一个构造函数,Int
是一个构造函数时,你能进一步说明你的意思吗?这听起来有悖常理。@MarkCanlasChar
和Int
是类型构造函数吗?一旦你有了整个苹果
(* -> *)
(* -> ((* -> *) -> *))