【问题标题】:why my attempt to add to the third and fourth element of a tuple in a list dont work?为什么我尝试添加到列表中元组的第三个和第四个元素不起作用?
【发布时间】:2021-03-11 18:11:14
【问题描述】:

我要一个数据学生和一个类型类:

data Student = Student {nome :: String
                        , stdNumber :: Int
                        , approvedClass :: Int
                        , failedClass :: Int
                        }
type Class = [Student]

我正在尝试将更多批准的学生添加到所有学生中,但我不知道该怎么做。我已经有了这个:

getStudent :: Class-> String -> Maybe Student
getStudent [] _ = Nothing
getStudent (student:xs) s
    | name student == s = Just student
    | otherwise = getStudent xs s


addClasses :: Student-> Int -> Int -> Student
addClasses student aC fC =
    student { approvedClass = approvedClass student + aC
            , failedClass = failedClass student + fC
            }


addClassesToAllStd :: Class-> [(String, Int, Int)] -> Class
addClassesToAllStd cl [] = cl
addClassesToAllStd  [] _ = []
addClassesToAllStd ((Student name _ approvedClass failedClass):xs) ((n,aC,fC):ys) = [(Student _ _ approvedClass+aC failedClas+fC)] ++ addClassesToAllStd xs ys

但我不知道如何检查我是否添加到正确的学生?而且我不明白为什么这不起作用(即使没有检查我是否添加到正确的学生)?

这是一个应该如何工作的示例:

>french1 = addClassesToAllStd french [("Emma",5,1),
("Max",3,3), ("Carol",4,2)]
> carol = getStudent french1 "Carol"
> approvedClass carol
4
> failedClass carol
4
> max = getStudent french "Max"
> approvedClass max
3
> failedClass max
3

法语是french = [("Emma",0,0),("Max",0,0), ("Carol",0,0)]

【问题讨论】:

  • 你怎么知道它不起作用?

标签: list haskell types tuples


【解决方案1】:

第一件事是你不能只是省略值而离开__ 是一个占位符,你可以在开发过程中留下,它会显示一些推断的类型信息,可以帮助你理解可以用什么来替换它。所以,首先让我们填写_ 并修复一些语法错误:

data Student = Student { name          :: String
                       , stdNumber     :: Int
                       , approvedClass :: Int
                       , failedClass   :: Int
                       } deriving (Show)
type Class = [Student]

getStudent :: Class -> String -> Maybe Student
getStudent [] _ = Nothing
getStudent (student:xs) s
    | name student == s = Just student
    | otherwise = getStudent xs s

addClasses :: Student -> Int -> Int -> Student
addClasses student aC fC =
    student { approvedClass = approvedClass student + aC
            , failedClass = failedClass student + fC
            }

addClassesToAllStd :: Class -> [(String, Int, Int)] -> Class
addClassesToAllStd cl [] = cl
addClassesToAllStd  [] _ = []
addClassesToAllStd ((Student name num approvedClass failedClass):xs) ((n, aC, fC):ys) =
  Student name num (approvedClass + aC) (failedClass + fC) : addClassesToAllStd xs ys

现在,这可行,但前提是您以与学生相同的顺序提供 [(String, Int, Int)]。为了解决这个问题,我们必须通过[(String, Int, Int)] 为每个学生查找具有指定字符串的元组并增加approvdedClassfailedClass 值:

addClassesToAllStd :: Class -> [(String, Int, Int)] -> Class
addClassesToAllStd cl [] = cl
addClassesToAllStd [] _  = []
addClassesToAllStd (x:xs) ys = x':addClassesToAllStd xs ys
  where
    x' = foldr updateStudent x ys
    updateStudent :: (String, Int, Int) -> Student -> Student
    updateStudent (name', ac', fc') s@Student { name = name, approvedClass = ac, failedClass = fc }
      | name == name' = s { approvedClass = ac + ac', failedClass = fc + fc' }
      | otherwise     = s

我们也可以完全相反:遍历[(String, Int, Int)],并在每次迭代中遍历学生列表,找到匹配的列表并增加他们的approvedClassfailedClass 值。

【讨论】:

    猜你喜欢
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多