好吧,弱类型和强类型的定义很模糊。此外,由于最接近“强类型”的通用用法是指难以转换类型的事物,因此不再进一步描述更强大的类型系统。这就像在说,如果您的负重不超过30磅,则说明您很虚弱,而每个可以举更多的人都属于“强”类别-这是一种误导性区分。
所以我更喜欢定义:
- 弱类型系统使用类型来阻止您执行某些操作(例如错误)
- 强类型系统使用类型为您做事
我对您有帮助是什么意思?好吧,让我们研究一下在Servant框架中编写图像转换API(在Haskell中,但是您实际上并不需要知道它,您将会看到...)
{-# LANGUAGE
TypeOperators,
DataKinds
#-}
import Codec.Picture
import Data.Proxy
import Network.Wai.Handler.Warp (run)
import Servant
import Servant.JuicyPixels
main :: IO ()
main = run 8001 conversion
这就是说,我们希望一些模块包括Servant软件包和Servant的JuicyPixels插件,并且该程序的主要切入点是使用Warp后端在服务器上的端口8001上运行“转换”功能。忽略语言位。
conversion :: Application
conversion = serve (Proxy :: Proxy ConversionApi) handler
也就是说,转换功能是服务器,其中API必须与类型“ ConversionApi”匹配,并且请求由该功能处理 handler
type ConversionApi
= ReqBody '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage
:> Post '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage
这是指定ConvesionApi
类型。它说我们应该接受列表'[BMP,GIF,JPEG 50,PNG,TIFF,RADIANCE]指定的传入内容类型,并将它们作为DynamicImage处理,并且我们应该返回转换为相同内容范围的DynamicImage类型。不必担心:>意味着什么,现在就将其视为快乐的魔法。
因此,根据我的首选定义,弱类型系统现在可以确保类似:
- 您不会返回错误的外发内容类型
- 您不会将传入的请求解析为错误的内容类型
- 如果我们的服务器更为复杂,它将阻止我们创建格式错误的URI,但是实际上我们并未返回任何包含链接的HTML页面(而且类型确保我们不能这样做!)
- 一个真正雄心勃勃的弱类型系统甚至可能检查以确保我们详尽地处理所有传入和传出的内容类型,从而使该类型还可以用作规范文档,而不仅仅是约束。
考虑到上述定义,所有崇高目标,但实际上不足以成为强类型系统。现在我们去的硬符合此规范的实际编写代码的一部分。在一个非常强大的类型系统中,我们编写:
handler = return
然后我们完成了。就这样,不再需要编写任何代码。这是一个完全可操作的Web服务器(以我错失的任何错字为模)。该类型已告知编译器根据我们定义和导入的类型和包(技术上为模块)创建Web服务器所需的一切。
那么,您如何学习在主要应用程序规模上做到这一点呢?嗯,与在较小规模的应用程序中使用它们并没有太大区别。绝对类型不关心编写与它们有关的多少代码。
运行时类型检查是您可能要避免的事情,因为这样做可以消除大量的好处,并允许类型使您的项目更复杂地工作,而不是使类型简化。
因此,这基本上只是练习用类型对事物建模的问题。建模事物(或一般构建事物)的两种主要方法是自下而上和自上而下。自上而下的操作从最高级别的操作开始,并且在构建模型时,会有一部分将建模推迟到以后。自下而上的建模意味着您从基础操作开始,就像从基础功能开始一样,然后构建越来越大的模型,直到您完全掌握了项目的操作。自下而上更具体,构建起来可能更快,但自上而下可能会更好地告知您的下层模型其实际行为方式。
实际上,类型是程序与数学之间的关系,因此,对于程序的复杂程度或您可以“完成”对其的了解,实际上并没有上限。实际上,高等大学课程以外的所有资源都专门用于类型如何以某种特定语言工作,因此您也需要做出决定。
尽我所能,类型可以像这样分层:
- 类型很弱,例如JavaScript,其中定义了[] + {}
- 像Python这样的弱类型,您无法在其中进行[] + {},但是直到尝试
- 像C或Java这样的弱类型,您无法执行[] + {},但是在编译时会进行检查,但是您没有更高级的类型功能
- 跨越弱类型和强类型之间的边界,例如C ++模板元编程和更简单的Haskell代码,其中类型仅用于强制属性。
- 完全进入强类型化,例如更复杂的Haskell程序,其中类型执行操作,如上所示
- 类型非常强的类型(例如Agda或Idris),其中类型和值相互作用并且可以相互约束。这与类型系统一样强大,并且在其中进行编程与编写有关程序功能的数学证明相同。注意:在Agda中编码不是按字面意义写数学证明,类型是数学理论,具有这些类型的函数是证明这些理论的构造性例子。
通常,此列表越靠后,各种类型就可以为您提供更多帮助,但是到最后,您正爬入平流层,空气变得越来越稀薄-包装生态系统要小得多,与找到相关的库相比,您必须自己编写更多的东西。随着您的深入,进入障碍也越来越高,因为您必须真正了解类型系统才能编写大型程序。