首先,一些错别字:
data Course = Course {
id :: Int,
title :: String
} deriving (Eq, Show)
请注意添加了数据构造函数名称(“Course”)以及从“derives”更改为“deriving”。
data Req = Single Course
| Any [Req]
| All [Req]
deriving Show
同样在这里。
satisfies :: [Course] -> Req -> Bool
将类型从 [Courses] 更改为 [Course]。
course1 = Course 1 "One"
course2 = Course 2 "Two"
course3 = Course 3 "Three"
course4 = Course 4 "Four"
course5 = Course 5 "Five"
req1 = Single course2
req2 = Any [Single course2, Single course3, Single course5]
req3 = All [Single course1, Single course2]
req4 = Any [req2, req3]
req5 = All [req4, req1]
一些测试数据。
satisfies cs (Single c) = c `elem` cs
匹配单一课程要求。另外两个很简单,因为它们所做的大部分工作已经在 Prelude 中定义,你可以像英语一样阅读它们:
satisfies cs (Single c) = c `elem` cs
satisfies cs (Any reqs) = any (satisfies cs) reqs
satisfies cs (All reqs) = all (satisfies cs) reqs
以下是您朋友的类型签名any
和all
:
any :: (a -> Bool) -> [a] -> Bool
all :: (a -> Bool) -> [a] -> Bool
它们都采用布尔函数并为列表的每个成员测试它。由于我们有一个需求列表和一个测试函数(它satisfies
递归地使用并部分应用于被免除的课程),我们可以直接使用它们。
让我们测试一下:
*TestSO15213421> satisfies [course1] req1
False
*TestSO15213421> satisfies [course2] req1
True
*TestSO15213421> satisfies [course1, course2] req1
True
*TestSO15213421> satisfies [course1, course2] req1
True
*TestSO15213421> satisfies [course1, course2] req3
True
*TestSO15213421> satisfies [course1, course3] req3
False
*TestSO15213421> satisfies [course1, course3] req2
True
*TestSO15213421> satisfies [course4] req2
False
*TestSO15213421> satisfies [course4] req5
False
*TestSO15213421> satisfies [course5] req2
True
*TestSO15213421> satisfies [course4] req4
False
*TestSO15213421> satisfies [course2] req4
True
*TestSO15213421> satisfies [course2, course3] req4
True
*TestSO15213421> satisfies [course5, course3] req4
True
*TestSO15213421> satisfies [course5, course3] req5
False
一切如预期。