You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

完善addUserDislikes函数:实现点赞点踩互斥及移除已点赞用户

解决方案:完善Haskell电影点赞/点踩互斥逻辑

我来帮你搞定这两个相关的技术需求,核心是要保证用户在电影的点赞、点踩列表中只能存在于一处:


问题分析

你当前的addUserDislikes函数只实现了把用户添加到点踩列表的逻辑,但完全没处理点赞列表的清理——这就导致用户可能同时出现在两个列表里,不符合需求。而第一个需求「移除已点赞某部电影的用户」,其实是实现第二个需求的必要步骤。


优化后的代码实现

我们可以拆分逻辑,用辅助函数让代码更清晰易维护:

1. 先定义类型(如果你的项目里已有定义可跳过)

假设你的电影数据结构是这样的,要是实际类型不同,对应调整字段即可:

type Title = String
type User = String
-- 电影元组:(标题, 描述, 年份, 点赞用户列表, 点踩用户列表)
type Film = (Title, String, Int, [User], [User])

2. 辅助函数:处理单部电影的点踩更新

写一个专门处理单部电影的函数,负责完成「移除点赞记录 + 添加点踩记录」的核心逻辑:

updateFilmDislikes :: User -> Film -> Film
updateFilmDislikes user (ti, di, yr, like, dislike) =
  -- 第一步:强制从点赞列表移除当前用户,确保互斥性
  let cleanedLikes = filter (/= user) like
      -- 第二步:如果用户还没在点踩列表,就添加进去(避免重复点踩)
      updatedDislikes = if elem user dislike then dislike else user : dislike
  in (ti, di, yr, cleanedLikes, updatedDislikes)

3. 完善后的addUserDislikes主函数

主函数只需要遍历电影数据库,对目标标题的电影应用更新逻辑即可:

addUserDislikes :: Title -> User -> [Film] -> [Film]
addUserDislikes targetTitle user db = map updateFilm db
  where
    updateFilm film@(currentTitle, _, _, _, _)
      -- 只处理标题匹配的目标电影
      | currentTitle == targetTitle = updateFilmDislikes user film
      -- 其他电影保持原样
      | otherwise = film

可选:独立实现「移除已点赞用户」的函数

如果你需要一个单独的函数来处理用户取消点赞的场景(也就是你的第一个需求的独立实现),可以这样写:

removeUserLikes :: Title -> User -> [Film] -> [Film]
removeUserLikes targetTitle user db = map updateFilm db
  where
    updateFilm film@(currentTitle, di, yr, like, dislike)
      | currentTitle == targetTitle = (currentTitle, di, yr, filter (/= user) like, dislike)
      | otherwise = film

逻辑说明

  • 互斥性保证:updateFilmDislikes函数首先用filter清理点赞列表,确保用户不会同时出现在两个列表中;
  • 避免重复操作:添加点踩记录前会检查用户是否已存在,防止无效的重复点踩;
  • 代码可读性:拆分辅助函数后,主逻辑更简洁,后续扩展(比如添加取消点踩功能)也更方便。

内容的提问来源于stack exchange,提问作者sam786

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:22:41