我正在学习(再次)haskell,我有以下代码:
import qualified Data.Map as Map
data Union = Union
{
father :: Int,
mother :: Int,
offspring :: [Int]
}
deriving Show
data Person = Person
{
uid :: Int,
name :: String,
parentUnion :: Maybe Union,
unions :: [Union]
}
deriving Show
family :: Map.Map Int Person
family = Map.fromList []
addPerson :: (Map.Map Int Person) -> Person -> (Map.Map Int Person)
addPerson family person
| Map.member puid family = error "Repeated id"
| otherwise = Map.insert puid person family
where puid = uid person
现在有了更多功能,我将拥有相当多的Map.Map Int Person
类型。有没有办法定义类型Family
,它与Map.Map Int Person
相同,所以我可以拼写:
addPerson :: Family -> Person -> Family
我天真的做法:
data Family = Map.Map Int Person
给了我一个很好的错误:
Qualified constructor in data type declaration
答案 0 :(得分:3)
是。创建"输入同义词"这样,只需使用type
代替data
:
type Family = Map.Map Int Person
这使得Family
完全与写出Map.Map Int Person
相同。实际上,错误消息有时会写出完整版本而不是同义词,因此请为此做好准备。
另一种选择是使用newtype
:
newtype Family = Family (Map.Map Int Person)
不同之处在于,newtype
版本与名称一样,是 new 类型:它与Map.Map Int Person
不直接兼容。如果您尝试使用另一个预期的那个,您将收到错误。这可能对您的示例不太有用,但可用于编码类型中的其他不变量。
newtype
版本与data
构造几乎相同:
data Family = Family (Map.Map Int Person)
它还引入了一个新的构造函数Family
,它只接受一个参数。但是,与普通数据类型不同,它仅存在于编译时; Family
和Map.Map Int Person
的运行时表示仍然完全相同。