Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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,我要做这个项目,我有点卡住了。我知道这不是很复杂,但我已经没有主意了 我定义了这些类型: -- Types type Title = String type Director = String type Year = Int type Mark = Int type Rating = (String, Int) -- Define Film type here type Film = (Title, Director, Year, [Rating]) -- Define database

我要做这个项目,我有点卡住了。我知道这不是很复杂,但我已经没有主意了

我定义了这些类型:

-- Types
type Title = String
type Director = String
type Year = Int
type Mark = Int
type Rating = (String, Int)

-- Define Film type here
type Film = (Title, Director, Year, [Rating])


-- Define database type here
type Database = [Film]


testDatabase :: [Film]
testDatabase =
  [("Casino Royale", "Martin Campbell", 2006, [("Garry",8),("Dave", 0)])
  ,("Blade Runner", "Ridley Scott", 1982, [("Amy",5),("Dave", 9]),
  ,("The Fly", "David Cronenberg", 1986, [("Fred",7),("Dave", 4)])
  ]
所以现在我必须显示平均评级,然后我必须显示平均评级等于或高于6的电影

你能给我一些提示/指导吗?谢谢

更新:

谢谢你的回复,但是因为我已经完成了项目的一半,我认为更改数据类型太晚了,因为我必须重新考虑所有事情

我尝试过,但显示功能不起作用,我不知道为什么:

filmRating :: [Rating] -> Int
filmRating rating = div (sum [r | (_,r) <- rating]) (length rating)

averageFilm :: Film -> Int
averageFilm (t, d, y, r) = filmRating r


sixOrHigher :: Int -> Bool
sixOrHigher average
    | average <= 6 = True
    | otherwise = False


displayAverage :: Database -> String
displayAverage database = displayFilms (filter ((sixOrHigher (averageFilm)) database))
filmRating::[Rating]->Int
电影评级=div(和[r |(u,r)Int
平均胶片(t,d,y,r)=胶片评级r
六或更高::整数->布尔
六个或更高的平均值
|平均字符串
displayAverage数据库=displayFilms(过滤器((六个或更高的(averageFilm))数据库))
更新2:

经过数小时的脑残和咒骂,我找到了解决办法:)

再次感谢大家

这是:

averageFilm :: Film -> Int
averageFilm (t, d, y, r) = filmRating r

averageFilms :: Database -> [Int]
averageFilms database = map (averageFilm) database

sixOrHigher :: Int -> Bool
sixOrHigher average
            | average <= 6 = True
            | otherwise = False


checkAllIfHigher :: Film -> Bool 
checkAllIfHigher film = (sixOrHigher (averageFilm film))

displayAverage :: Database -> String
displayAverage database = displayFilmsAverage (filter (checkAllIfHigher) database)


displayFilmsAverage :: Database -> String
displayFilmsAverage database = concat(map (displayFilmAverage ) database)
averageFilm::Film->Int
平均胶片(t,d,y,r)=胶片评级r
averageFilms::数据库->[Int]
averageFilms数据库=地图(averageFilm)数据库
六或更高::整数->布尔
六个或更高的平均值
|平均布尔
检查所有高胶片=(六张或更高(平均胶片))
displayAverage::数据库->字符串
displayAverage database=displayFilmsAverage(筛选(checkAllIfHigher)数据库)
displayFilmsAverage::数据库->字符串
displayFilmsAverage数据库=concat(地图(displayFilmAverage)数据库)

首先:尽可能选择数据类型而不是元组+类型同义词。如果您希望为现有类型指定不同的名称,则类型同义词很好,但定义自定义数据类型也可以提供类型安全性,因此您不能简单地使用任何元组而不是评级

因此,您的数据类型将变成:

data Rating = Rating { ratingUsername :: String
                     , ratingStars :: Int 
                     }

data Film = Film { filmTitle :: String
                 , filmDirector :: String
                 , filmYear :: Int
                 , filmRatings :: [Rating]
                 }
以及您的测试数据库:

testDatabase :: [Film]
testDatabase = [ Film "Casino Royale" "Martin Campbell" 2006
                        [Rating "Garry" 8, Rating "Dave" 0]
               , Film "Blade Runner" "Ridley Scott" 1982
                        [Rating "Amy" 5, Rating "Dave" 9]
               , Film "The Fly" "David Cronenberg" 1986
                        [Rating "Fred" 7, Rating "Dave" 4]
               ]
使用我们的新数据类型,我们可以通过
filmRatings::film->[Rating]
仅选择影片的收视率

解决这类问题的一个好方法是首先考虑所需的类型注释,然后在

因此,要计算平均评分,请尝试以下步骤:

  • 定义一个函数来计算平均评分(您可能希望查看例如
    foldl
    和朋友)

  • 若要基于评级的属性进行筛选,则可以使用具有适当谓词的筛选器:

    filter :: (a -> Bool) -> [a] -> [a]
    
    其中
    (a->Bool)
    在您的例子中是
    Film->Bool
    ,因此您可以编写一个函数

    goodFilm :: Film -> Bool
    
    并使用之前定义的averageStars函数比较评级是否足够高


第一步:编写一个函数
::Film->[Rating]
,获取一部电影的所有评级。然后,一个函数
::[Rating]->Double
进行平均。然后您可以查看提供的排序函数。查看
map
函数和
sum::Num a=>[a]->a
长度::[a]->Int
函数。稍后您需要使用
过滤器
函数来选择影片。您可以在上搜索函数。您的
标记
类型同义词没有在任何地方使用-可能您是想在定义
速率
时使用它?
goodFilm :: Film -> Bool