database - 不在范围内:数据构造函数“Song” - Haskell
问题描述
type Song = (String, String, Int) --(title, artist, sales)
database :: [Song]
database = [("Amon Amarth","Ravens flight", 1),
("Amon Amarth","Shield wall", 11),
("Amon Amarth","The way of vikings", 105),
("Elijah Nang","Journey to the west", 1000),
("Elijah Nang","Tea house", 7),
("Pink Floyd","Wish you were here", 123),
("Amon Amarth","Raise your horns", 9001),
("NLE Choppa","Walk 'em down'", 69420),
("Elijah Nang","Kumite", 1337),
("NLE Choppa","Shotta flow 6", 511),
("Pink Floyd","Comfortably numb", 9),
("Pink Floyd","Shotta flow 6", 711), -- changed to match the name of an nle choppa song as requested
("Johannes Chrysostomus Wolfgangus Theophilus Mozart","Requiem", 10203948),
("Elijah Nang","Kenjutsu water style", 1),
("NLE Choppa","Shotta flow 5", 1),
("Pink Floyd","High hopes", 1),
("Amon Amarth","Deceiver of the gods", 1),
("Johannes Chrysostomus Wolfgangus Theophilus Mozart","Turkish march", 1),
("Chance The Rapper","Cocoa butter kisses", 1),
("Chance The Rapper","Favourite song", 1),
("Chance The Rapper","Hot shower", 1),
("Chance The Rapper","High hopes", 1)]
getTrackSale :: Int -> String -> String -> String --(index, artist, track, sales)
getTrackSale index artist track
| ((getArtist(database!!index) == artist) && (getTrack(database!!index) == track)) = getTrackSale(database!!index)
| otherwise = getTrackSale(index + 1 artist track)
task2 = getTrackSale(0 "Chance The Rapper" "Hot Shower")
getArtist :: Song -> String
getArtist (Song y _ _) = y
getTrack :: Song -> String
getTrack (Song _ z _) = z
getSale :: Song -> Int
getSale (Song _ _ x) = x
我无法弄清楚这意味着什么或如何解决它,我之前已经编写了与三个“get”函数相同的函数并且它们没有问题,但我之前确实使用了“type”声明,所以我想就是这样。我有使用相同类型声明的示例代码,它工作正常,所以我在这里有点迷失。
解决方案
你写
type Song = (String, String, Int)
这意味着 thatSong
是 的类型同义词。(String, String, Int)
也就是说, aSong
实际上只是一个有序三元组,使用有序三元组构造函数构造(,,)
。但后来你写
getArtist :: Song -> String
getArtist (Song y _ _) = y
getTrack :: Song -> String
getTrack (Song _ z _) = z
getSale :: Song -> Int
getSale (Song _ _ x) = x
(不存在的)Song
数据构造函数上的模式匹配。
您可以通过编写来坚持类型同义词
getArtist :: Song -> String
getArtist (y, _, _) = y
等等。或者您可以创建Song
自己的数据类型:
data Song = Song
{ getArtist :: String
, getTrack :: String
, getSale :: Int }
在这种情况下,您必须修改database
定义以使用Song
构造函数。使用自定义数据类型声明更符合习惯和更自文档化,它使 Haskell 的类型系统做更多的工作来帮助您发现代码中的错误。作为一般规则,我建议 Haskell 初学者完全避免使用类型同义词,而更有经验的 Haskell 程序员仅在某些特殊情况下很少使用它们。特别是,类型同义词与扩展结合起来非常有用,与and扩展TypeFamilies
结合起来有些用处,但根据我的经验,其他方面往往更令人困惑而不是有用。ConstraintKinds
RankNTypes
推荐阅读
- django - django视图没有重定向
- qt - 如何在 QML 中找到递归重新排列的来源
- crc - 这是哪种 CRC 算法(由 BBC 微型磁带归档系统使用)?
- c++ - 什么是结膜炎?
- android - Xamarin Forms Maps MoveToLastRegionOnLayoutChange 未按预期工作
- c# - 有效地找到两个序列中的第一个公共元素
- reactjs - 显示来自 Mongodb (MERN) 的图像
- c - 如何让我的 C 代码读取并显示 C 文件中的多行?
- php - 使用PHP将数据从csv导入pdf表格
- flutter - Flutter:如何定位当前可访问的 Scaffold