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

Haskell递归函数开发:实现学生列表的部分科目添加功能

Solution for Updating Student's Liked Subjects Recursively

Alright, let's walk through how to build this recursive function for your Haskell student database. First, let's restate the requirements clearly to make sure we're on the same page:

  • We need a recursive function that processes a list of Student records
  • When we find a student matching a specified name, we check if a target subject is not already in their liked subjects list
  • If the subject isn't present, we add it to their liked subjects; if it is, we leave the student record as-is
  • All other students in the list remain unchanged

First, Let's Confirm the Existing Definitions

Here's the Student data type and database you provided, formatted as code:

data Student = Student String Int [String] [String] deriving (Show, Read)

db :: [Student] 
db = [ Student "JenDavis" 54 ["Physics", "Maths"] ["Biology", "English"], 
       Student "BenBlue" 62 ["Art", "English"] ["Maths", "PE"], 
       Student "JaydenBrimes" 56 ["Chemistry", "PE"] ["Music", "Maths"] ]

Step 1: Define the Function Type Signature

Our function will take three arguments: the target student's name, the subject to add, and the list of students. It will return the updated list of students. So the type signature is:

updateStudentLikes :: String -> String -> [Student] -> [Student]

Step 2: Implement the Recursive Function

We'll use standard list recursion here, with a base case for empty lists and a recursive case for processing each element:

updateStudentLikes _ _ [] = []  -- Base case: empty list stays empty
updateStudentLikes targetName targetSubj (student@(Student name age liked disliked):rest)
  | name == targetName = 
      if targetSubj `notElem` liked
        then Student name age (targetSubj : liked) disliked : updateStudentLikes targetName targetSubj rest
        else student : updateStudentLikes targetName targetSubj rest
  | otherwise = student : updateStudentLikes targetName targetSubj rest

Let's Break Down the Logic

  • Base Case: If we're given an empty list of students, we just return an empty list—there's nothing to update.
  • Recursive Case: We pattern match on the first student in the list (using @ to keep the full student reference for later):
    1. If the student's name matches our target name:
      • Check if the target subject is not in their liked list using notElem
      • If it's missing, create a new Student record with the subject added to the front of the liked list, then recursively process the rest of the list
      • If the subject is already present, we keep the original student record and move on to the rest of the list
    2. If the name doesn't match, we keep the original student and recursively process the remaining students

Testing the Function

Let's test this with an example. Suppose we want to add "Maths" to BenBlue's liked subjects (since it's currently in his disliked list):

-- Call the function
updatedDb = updateStudentLikes "BenBlue" "Maths" db

-- Print the result
main = print updatedDb

The output will show BenBlue's liked subjects now include "Maths":

[Student "JenDavis" 54 ["Physics","Maths"] ["Biology","English"],Student "BenBlue" 62 ["Maths","Art","English"] ["Maths","PE"],Student "JaydenBrimes" 56 ["Chemistry","PE"] ["Music","Maths"]]

Notes

  • We're prepending the new subject to the liked list (using targetSubj : liked) because prepending is O(1) in Haskell, which is more efficient than appending. If you need the list to stay in a specific order, you could use liked ++ [targetSubj], but that's O(n) time.
  • The function is pure, meaning it doesn't modify the original database—it returns a new list with the updated student record. This aligns with Haskell's immutable data principles.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:30:44