要回答这些问题,您需要一个基础:表达式e
具有类型是什么意思t
?您可以为 之类的原语给出任意答案getProgName
,但您不必这样做。相反,请查看表达式和类型的含义。当由 表示的值(即作为数学值的含义)属于由 表示的集合时,就说表达式e
具有类型。t
e
e
t
现在考虑t == String
。我们想要String
拥有什么意义?同样,这里有很多选择空间。然而,用最简单的数学定义选择有用的候选人有很多优点。在 HaskellString == [Char]
中,我们真正讨论的是[]
和的含义。Char
我所知道的最引人注目的简单候选词是[]
表示列表(序列)和Char
表示字符,因此表示字符String
序列,即“字符串”。
选择String
意味着字符串,现在我们可以询问是否有可能getProgName :: String
. 如果是这样,那么 的含义getProgName
必须是一个字符序列。但是,没有单一的字符序列可以捕捉到getProgName
. (编辑:据推测,getProgName
当它出现在不同名称的程序中时,您希望产生不同的字符串。)因此,我们必须选择不同的类型,例如(但不一定)IO String
,或者我们必须选择更复杂的含义String
. 后一条路线起初可能看起来很吸引人,直到您考虑到深层含义。纯函数式(更准确地说是“外延”)编程支持实用、严谨的推理,这要归功于使用简单的含义,如序列,而不是复杂的含义,如来自某种环境的函数,包括操作系统、机器执行上下文。
有关密切相关的评论和讨论,请参阅博客文章Haskell 中的纯度概念。
编辑:我认为 Peter Landin(Haskell 的祖父)用他对“外延式编程”(或“真正的函数式编程”)的定义表达得最好,他建议将其作为“声明式”和“函数式”编程等模糊术语的实质性替代. 有关参考、引用和简短评论,请参阅帖子Haskell是纯函数式语言吗?.