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

时间:2016-03-13 18:07:36

标签: haskell parameters algebraic-data-types

我定义了两种数据类型。

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作为参数传递给许多函数,但它不起作用。

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

1 个答案:

答案 0 :(得分:2)

您没有将学生传递给每个学生(至少,不是明确地);您正试图在函数的定义中使用数据构造函数。 (实际上,您在几个地方混淆了传递值的数据构造函数。)例如,这里给出了check值和Inscription值的Student的正确定义,返回是否给定学生在第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