Haskell如何将许多数据类型参数传递给函数



我定义了两种数据类型。

type LastName = String 
type FirstName = String
type CodeP = Int 
type CodeS = String
type CodeI = Int
type GroupNb = Int
type Session = Int
Data Inscription = Inscription CodeS GroupNb Session deriving (Show, Eq)
Data Student = Student CodeS LastName FirstName CodeP

我想获得学生在课程 1 期间关注的所有 GroupNb 的列表。我的问题是我不知道如何将这两种数据类型作为所需函数的参数传递。这是我编写的函数(不起作用):

getCodeS :: Student -> CodeS
getCodeS (Student codeS _ _ _) = codeS
check :: Inscription -> Student -> Bool 
check (Inscription codeS _ Session) = codeS == (getCodeS Student) && Session == 1  
filterGroups :: [Inscription] -> Student -> [Inscription]
filterGroups g = filter check g Student
getGroupNb :: Inscription -> GroupNb
getGroupNb (Inscription _ groupNb _) = groupNb
stuGroupNb :: [Inscription] -> Student -> [groupNb]
stuGroupNb groupX = map getGroupNb (filterGroups groupX Student)

因此,我正在尝试将 Student 作为参数传递给许多函数,但它不起作用。

如何将两种数据类型参数传递给函数?

您没有将学生传递给每个学生(至少不是显式传递);您正在尝试在函数的定义中使用数据构造函数。(事实上,您将数据构造函数与多个位置的传递值混淆了。例如,下面是给定Inscription值和Student值的check的正确定义,返回给定学生是否在会话 1 期间注册。

check :: Inscription -> Student -> Bool
check (Inscription codeS _ session) student = codeS == (getCodeS student) && session == 1

请注意使用 student 作为 check 的第二个参数。此外,session 是在模式匹配期间要绑定的变量的名称,而不是之前定义的类型别名,因此它必须以小写字母开头。由于会话在此处硬编码为 1,因此您可以基于该模式匹配,而不是在正文中包含单独的比较:

check :: Inscription -> Student -> Bool
check (Inscription codeS _ 1) student = codeS == (getCodeS student)
check _ _ = False

对于filterGroups :: [Inscription] -> Student -> [Inscription],正确的定义是filterGroups g student = filter (x -> check x student) g。因此,check更好的定义是交换参数,以便check :: Student -> Inscription -> Bool可以像这样使用:

filterGroups g student = filter (check student) g

在不更改check的情况下,您可以使用flip,但这会使阅读更加困难:

filterGroups g student = filter ((flip check) student) g

最新更新