我正在使用Haskell编程语言,并且具有Scala和Java开发人员的背景。
我正在阅读类型构造函数背后的理论,但是我无法理解是否可以将它们视为类型。我的意思是,在Scala中,您使用关键字class
或trait
定义类型构造函数。考虑List[T]
或Option[T]
。同样在Haskell中,使用相同的关键字data
,该关键字用于定义新类型。
那么,类型构造函数也就是类型吗?
最佳答案
让我们看一个类比:函数。在某些数学分支中,函数称为值构造函数,因为这就是它们的作用:您将一个或多个值放入其中,然后它们会从中构造出新的值。
除了在类型级别上,类型构造器是完全一样的:您将一个或多个类型放入其中,然后从中构造一个新类型。从某种意义上说,它们是类型级别的函数。
现在,以我们的类比为例:您所提问题的类比是什么?好吧,是这样的:“可以将值构造函数(即函数)视为函数式编程语言中的值吗?”
答案是:它取决于编程语言。现在,对于函数式编程语言,几乎所有(如果不是全部)答案都是"is"。这取决于您对“功能性编程语言”的定义。有些人将功能性编程语言定义为具有功能作为值的编程语言,因此根据定义,答案将是简单的"is"。但是,有些人将功能性编程语言定义为不允许产生副作用的编程语言,在这种语言中,功能不一定就是值。
最著名的例子可能是约翰·巴克(John Backus)的FP,来自他的开创性论文《编程可以从冯·诺伊曼风格中解放出来吗? –一种功能样式及其程序代数。在FP中,存在“功能类”事物的层次结构。函数只能处理值,而函数本身不是值。但是,有一个“函数”的概念,它是“函数构造函数”,即它们可以将函数(以及值)作为输入和/或将函数作为输出,但不能将函数作为输入和/或将函数作为输出。
因此,FP可以说是一种功能编程语言,但它没有功能作为值。
注意:作为值的函数也称为“一等函数”,将函数作为输入或将其作为输出返回的函数称为“高阶函数”。
如果我们看一些类型:
1 :: Int
[1] :: List Int
add :: Int → Int
map :: (a → b, List a) → b
您可以看到我们可以轻松地说:任何类型中带有箭头的值都是一个函数。类型中带有多个箭头的任何值都是高阶函数。
同样,类型构造函数也是如此,因为除了类型级别外,它们实际上是相同的东西。在某些语言中,类型构造函数可以是类型,而在某些语言中则不能。例如,在Java和C♯中,类型构造函数不是类型。例如,您不能在C cannot中使用
List<List>
。您可以用Java写下List<List>
类型,但这会产生误导,因为两个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♯却没有。
但是,当我们查看您的问题时,情况会很复杂:
So, are type constructors also types?
不是,不是至少没有我知道的任何语言。看到,虽然您可以拥有将类型构造函数作为输入和/或将它们作为输出返回的更高类型的类型构造函数,但是您不能具有以类型构造函数作为其类型的表达式或值,变量或参数。您不能使用采用
List
或返回List
的函数。您不能具有Monad
类型的变量。但是,您可以具有Int
类型的变量。因此,很明显,类型和类型构造函数之间是有区别的。
关于scala - 是否可以将类型构造函数视为函数式编程语言中的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54620961/