我正在使用Haskell编程语言,并且具有Scala和Java开发人员的背景。
我正在阅读类型构造函数背后的理论,但是我无法理解是否可以将它们视为类型。我的意思是,在Scala中,您可以使用关键字class
或trait
定义类型构造函数。想想List[T]
还是Option[T]
。同样在Haskell中,使用相同的关键字data
,用于定义新类型。
那么,类型构造函数也就是类型吗?
让我们看一个类比:函数。在某些数学分支中,函数被称为值构造函数,因为它们就是这样做的:您将一个或多个值放入其中,然后它们从中构造出新的值。
除了在类型级别上,类型构造器是完全一样的:您将一个或多个类型放入其中,然后从中构造一个新类型。从某种意义上说,它们是类型级别的函数。
现在,以我们的类比为例:您要问的问题是什么?好吧,是这样的:“可以将值构造函数(即函数)视为功能编程语言中的值吗?”
答案是:它取决于编程语言。现在,对于函数式编程语言,几乎所有(如果不是全部)答案都是“是”。这取决于您对“功能编程语言”的定义。有些人将功能性编程语言定义为具有功能作为值的编程语言,因此根据定义,答案将是简单的“是”。但是,有些人将功能性编程语言定义为不允许产生副作用的编程语言,在这种语言中,功能不一定就是值。
最著名的例子可能是约翰·巴克(John Backus)的FP,来自他的开创性论文《编程可以从冯·诺伊曼风格中解放出来吗?–一种功能样式及其程序代数。在FP中,存在“功能类”事物的层次结构。函数只能处理值,而函数本身不是值。但是,有一个“函数”的概念,它是“函数构造函数”,即它们可以将函数(以及值)作为输入和/或将函数作为输出,但不能将函数作为输入和/或将它们作为输出。
因此,FP可以说是一种功能编程语言,但它没有功能作为值。
注意:作为值的函数也称为“一等函数”,将函数作为输入或将其返回作为输出的函数称为“高阶函数”。
如果我们看一些类型:
1 :: Int
[1] :: List Int
add :: Int → Int
map :: (a → b, List a) → b
您可以看到我们可以轻松地说:任何类型中带有箭头的值都是一个函数。类型中带有多个箭头的任何值都是高阶函数。
同样,类型构造函数也是如此,因为除了类型级别外,它们实际上是相同的东西。在某些语言中,类型构造函数可以是类型,而在某些语言中则不能。例如,在Java和C♯中,类型构造函数不是类型。例如,您不能List<List>
在C♯中有一个。您可以用List<List>
Java写下类型,但这具有误导性,因为两者List
的含义不同:第一个List
是类型构造函数,第二个List
是原始类型,因此实际上这并不是将类型构造函数用作类型。
与上面的类型示例等效吗?
Int :: Type
List :: Type ⇒ Type
→ :: (Type, Type) ⇒ Type
Functor :: (Type ⇒ Type) ⇒ Type
(请注意,我们总是这样Type
吗?的确,我们只在处理类型,所以我们通常不写Type
,而只是写*
,发音为“ Type”):
Int :: *
List :: * ⇒ *
→ :: (*, *) ⇒ *
Functor :: (* ⇒ *) ⇒ *
因此,Int
是一个合适的类型,List
是一个接受一个类型并产生一个类型→
的类型构造函数,(函数类型构造函数)接受两个类型并返回一个类型(假设仅一元函数,例如使用currying或passed tuples),并且Functor
是一个类型构造函数,它本身接受一个类型构造函数并返回一个类型。
这些“类型-类型”称为种。像函数一样,带有箭头的任何东西都是类型构造函数,带有多个箭头的任何东西都是类型较高的类型构造函数。
与函数一样,某些语言允许使用类型较高的类型构造函数,而某些则不允许。您在问题中提到的两种语言Scala和Haskell可以,但如上所述,Java和C♯则没有。
但是,当我们查看您的问题时,情况会很复杂:
那么,类型构造函数也就是类型吗?
不是,不是 至少没有我知道的任何语言。看到,虽然您可以拥有类型较高的类型构造函数,这些类型构造函数将类型构造函数作为输入和/或将它们作为输出返回,但是您不能具有以类型构造函数作为其类型的表达式或值,变量或参数。您不能使用接受List
或返回的函数List
。您不能具有类型的变量Monad
。但是,您可以具有type变量Int
。
因此,很明显,类型和类型构造函数之间是有区别的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句