Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 输出自定义数据类型列表的内容_Haskell - Fatal编程技术网

Haskell 输出自定义数据类型列表的内容

Haskell 输出自定义数据类型列表的内容,haskell,Haskell,我有一个自定义数据类型Movie=String Int[(String,Int)](电影名称年份[(粉丝,评级)],我想做几件事: 首先,我想做一个函数,对元组列表中的整数求平均值,然后只输出那个数。到目前为止,我有一个不完整的函数: sum :: Num a => [a] -> a sum [] = 0 sum (x:xs) = x + sum xs movieAvgRating :: Movie -> Float movieAvgRating = average . ra

我有一个自定义数据类型
Movie=String Int[(String,Int)]
(电影名称年份[(粉丝,评级)],我想做几件事:

首先,我想做一个函数,对元组列表中的整数求平均值,然后只输出那个数。到目前为止,我有一个不完整的函数:

sum :: Num a => [a] -> a
sum [] = 0
sum (x:xs) = x + sum xs
movieAvgRating :: Movie -> Float
movieAvgRating = average . ratings
avgRating::[DataType]->Int
avgRating[(电影a b[(影迷、评级)]]=sumRatings/(长度[])

在这里,我需要一个函数sumRatings在列表中递归并对所有评级求和,但我不确定从哪里开始

我在这里遇到的另一个问题是,我不确定将什么放在
的位置,因为我通常会给列表一个变量名,然后在那里使用它,但由于我已经将列表拆分以定义其他变量,所以我无法命名它


我希望这是有意义的,谢谢。

要先回答第二个问题,您可以绑定到一个变量,并使用
@
同时解压它:

avgRating [(Movie a b mylist@[(fan, rating)])] = …
还要注意的是,如果您不打算使用解包的变量,则Haskell约定将它们绑定到
\uuu

avgRating [(Movie _ _ mylist@[(fan, rating)])] = …
这有助于读者关注真正重要的东西

我不想只是给你递归问题的解决方案,因为学习编写递归函数是Haskell编程中一个重要且有益的部分。(如果你真的想让我破坏它,请让我在评论中告诉你。)然而,基本思想是你需要考虑两种不同的情况:基本情况(递归停止)和递归情况。作为例子,考虑内置的<代码>和<代码>函数:

sum :: Num a => [a] -> a
sum [] = 0
sum (x:xs) = x + sum xs
movieAvgRating :: Movie -> Float
movieAvgRating = average . ratings
这里,基本情况是当
sum
得到一个空列表时–它的计算结果仅为0。在递归情况下,我们假设
sum
已经可以生成一个较小列表的和,并扩展它以覆盖一个较大的列表


如果你在递归方面遇到了问题,Harold Abelson和Gerald Jay Sussman在麻省理工学院出版社(剑桥)1996年第2版中详细讨论了这个问题,从第21页开始()。这是Scheme,不是Haskell,但这两种语言非常相似——至少在这个概念层面上如此——因此每种语言都可以作为另一种语言的一个像样的模型。

首先回答第二个问题,您可以绑定到一个变量,然后使用
@
同时解包:

avgRating [(Movie a b mylist@[(fan, rating)])] = …
还要注意的是,如果您不打算使用解包的变量,则Haskell约定将它们绑定到
\uuu

avgRating [(Movie _ _ mylist@[(fan, rating)])] = …
这有助于读者关注真正重要的东西

我不想只是给你递归问题的解决方案,因为学习编写递归函数是Haskell编程中一个重要且有益的部分。(如果你真的想让我破坏它,请让我在评论中告诉你。)然而,基本思想是你需要考虑两种不同的情况:基本情况(递归停止)和递归情况。作为例子,考虑内置的<代码>和<代码>函数:

sum :: Num a => [a] -> a
sum [] = 0
sum (x:xs) = x + sum xs
movieAvgRating :: Movie -> Float
movieAvgRating = average . ratings
这里,基本情况是当
sum
得到一个空列表时–它的计算结果仅为0。在递归情况下,我们假设
sum
已经可以生成一个较小列表的和,并扩展它以覆盖一个较大的列表


如果你在递归方面遇到了问题,Harold Abelson和Gerald Jay Sussman在麻省理工学院出版社(剑桥)1996年第2版中详细讨论了这个问题,从第21页开始().这是Scheme,不是Haskell,但两种语言非常相似——至少在这个概念层面上是如此——以至于每一种语言都可以作为另一种语言的合适模型。

我猜您的数据结构定义为

data Movie = Movie String Int [(String, Int)]
虽然这是可行的,但当您有那么多字段时,使用它可能会有点麻烦

type Name = String
type Year = Int
type Rating = Int

data Movie = Movie
    { mName :: Name
    , mYear :: Year
    , mRatings :: [(Name, Rating)]
    } deriving (Eq, Show)
现在事情变得更加明确和容易处理了。
mName
mYear
mRatings
函数将获取一个
Movie
并从中返回相应的字段。您的
Movie
构造函数仍然以同样的方式工作,因此它不会破坏现有代码

要计算收视率的平均值,您确实需要一个函数来提取电影的所有收视率并将其聚合到列表中:

ratings :: Movie -> [Rating]
ratings mov = map snd $ mRatings mov
然后您只需要一个
average
函数。这将有点不同,因为您无法直接计算
Int
s的平均值,您必须转换为浮点类型:

average :: [Rating] -> Float   -- Double precision isn't really needed here
average rs = fromIntegral (sum rs) / fromIntegral (length rs)
fromIntegral
函数将
Int
转换为
Float
(实际的类型签名更一般一些)。由于
Int
s的
都是
Int
,列表的
长度始终是
Int
,因此需要将两者转换

现在,您可以将它们组合成一个函数:

sum :: Num a => [a] -> a
sum [] = 0
sum (x:xs) = x + sum xs
movieAvgRating :: Movie -> Float
movieAvgRating = average . ratings
现在,如果你需要计算几部电影的平均收视率,你可以对每部电影应用
收视率
,将它们聚合到一个收视率列表中,然后调用
平均值
。我建议你看看
concatMap
函数。你会想要做一个类似这样的函数

moviesAvgRating :: [Movie] -> Float
moviesAvgRating movs = average $ ???

我猜您的数据结构定义为

data Movie = Movie String Int [(String, Int)]
虽然这是可行的,但当您有那么多字段时,使用它可能会有点麻烦

type Name = String
type Year = Int
type Rating = Int

data Movie = Movie
    { mName :: Name
    , mYear :: Year
    , mRatings :: [(Name, Rating)]
    } deriving (Eq, Show)
现在事情变得更加明确和容易处理了。
mName
mYear
mRatings
函数将获取一个
Movie
并从中返回相应的字段。您的
Movie
构造函数仍然以同样的方式工作,因此它不会破坏现有代码

要计算收视率的平均值,您确实需要一个函数来提取一部电影的所有收视率,并将其聚合到