以下两段代码看起来非常相似.但是必须有一些差异,我希望有人可以指出它们.
data Animal = Cat | Dog
speak :: Animal -> String
speak Cat = "meowh"
speak Dog = "wouf"
Run Code Online (Sandbox Code Playgroud)
和
data Animal = Animal { speak :: String }
cat = Animal { speak = "meowh"}
dog = Animal { speak = "wouf" }
Run Code Online (Sandbox Code Playgroud)
Ben*_*son 25
好问题!你已经触及了软件工程的一个基本问题的核心.Per Wadler,它被称为表达式问题,并且,粗略地总结,问题是:
是否应该轻松添加新操作或新类型的数据?
您的第一个示例可以轻松地向现有动物添加新操作.我们可以Animal在不改变以下定义的情况下以各种方式处理值Animal:
numberOfTeeth :: Animal -> Int
numberOfTeeth Cat = 30
numberOfTeeth Dog = 42
food :: Animal -> String
food Cat = "Fish"
food Dog = "Sausages" -- probably stolen from a cartoon butcher
Run Code Online (Sandbox Code Playgroud)
缺点是很难添加新型动物.您必须添加新构造函数Animal并更改所有现有操作:
data Animal = Cat | Dog | Crocodile
speak :: Animal -> String
speak Cat = "miaow"
speak Dog = "woof"
speak Crocodile = "RAWR"
numberOfTeeth :: Animal -> Int
numberOfTeeth Cat = 30
numberOfTeeth Dog = 42
numberOfTeeth Crocodile = 100000 -- I'm not a vet
food :: Animal -> String
food Cat = "Fish"
food Dog = "Sausages"
food Crocodile = "Human flesh"
Run Code Online (Sandbox Code Playgroud)
您的第二个示例翻转矩阵,可以轻松添加新类型,
crocodile = Animal { speak = "RAWR" }
Run Code Online (Sandbox Code Playgroud)
但很难添加新功能 - 这意味着添加新字段Animal并更新所有现有动物.
data Animal = Animal {
speak :: String,
numberOfTeeth :: Int,
food :: String
}
cat = Animal {
speak = "miaow",
numberOfTeeth = 30,
food = "Fish"
}
dog = Animal {
speak = "woof",
numberOfTeeth = 42,
food = "Sausages"
}
crocodile = Animal {
speak = "RAWR",
numberOfTeeth = 100000,
food = "Human flesh"
}
Run Code Online (Sandbox Code Playgroud)
不要低估表达问题有多大的交易!如果您正在处理已发布的库,您可能会发现自己正在与您在代码库中从未遇到过的人所定义的操作或类型竞争无法更改.您必须仔细考虑您希望人们使用您的系统的方式,并决定如何确定图书馆的设计方向.
多年来,聪明人发明了许多解决表达问题的聪明方法,以支持新操作和新类型.使用最先进的编程语言的最先进功能,这些解决方案往往很复杂.在现实世界中,这只是工程师必须考虑的另一个权衡 - 解决表达问题值得代码复杂化它会导致什么?
| 归档时间: |
|
| 查看次数: |
274 次 |
| 最近记录: |