Ответ 1
Хороший вопрос! Вы поразили суть одной из фундаментальных проблем разработки программного обеспечения. 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
Недостатком является то, что трудно добавлять новые типы животных. Вы должны добавить новые конструкторы в 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"
Ваш второй пример переворачивает матрицу, делая ее легкой для добавления новых типов,
crocodile = Animal { speak = "RAWR" }
но трудно добавить новые функции - это означает добавление новых полей в 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"
}
Не стоит недооценивать, насколько велика сделка, проблема выражения! Если вы работаете над опубликованной библиотекой, вы можете столкнуться с операциями или типами, определенными кем-то, кого вы никогда не встречали в кодовой базе, которую вы не можете изменить. Вы должны тщательно подумать о том, как вы ожидаете, что люди будут использовать вашу систему, и решите, как ориентировать дизайн вашей библиотеки.
С годами умные люди изобрели множество умных способов решения проблемы выражения, для поддержки новых операций и новых типов. Эти решения, как правило, сложны, используя самые передовые функции самых современных языков программирования. В реальном мире это просто еще один компромисс, который нужно учитывать - решает проблему с выражением, стоящую за сложность кода, которую это вызовет?