为了提高类型签名的可读性,我们经常使用type关键字为现有类型创建别名。
比如,一个平面上的坐标通常由两个整数表示,这一点非常明显。但如果省略类型注解,就无法直观地看出这个二元组是用于表示位置(Position)还是其他用途。
为了解决这一问题,我们可以采用抽象数据类型的方法,定义一个构造子,使得Position的创建更加明确。然而,这种类型约束仍然相对较弱。为了使类型更加明确,我们可以使用newtype。
使用newtype后,如果忘记显式调用Position,类型检查就不会轻易通过。如果需要复用(Int, Int),newtype可以有效地避免混淆。以扫雷游戏为例,我们在一个9×9的Field上进行游戏,每个格子都使用Position类型表示其位置。同时,我们使用简单的方法放置地雷,通过随机数取模操作,确保余数在[0, n)之间。随机数的生成可以使用一个方程、初始种子和状态来实现。
虽然System.Random和State Monad的存在使得这个例子显得有些简单,但这也反映了newtype的封装能力。它可以确保同一类型在不同概念抽象中安全地使用,而且newtype定义的“新类型”在运行时没有额外成本。
另一个更“好”的例子是Data.Monoid模块中的Sum和Product类型。
Data.Coerce
原文:GHC/Coercible - HaskellWiki
下面给出一个NewType定义:
- 随机文章