我正在尝试解决F#中的练习。我必须编写一个可以区分书籍和电影的代码,并将其作为书籍或电影放在列表中。由于书籍没有文件大小,因此可以通过文件大小来区分。例如,如果我放入一本书,则代码必须将它添加为列表,就像电影一样。我将样本结果和输入链接起来。预先谢谢你。
type Movie =
{ movieName: string
duration: Nat
fileSize: Nat }
type Book =
{ bookName: string
pages: Nat }
type Activity =
| Watch of Movie
| Read of Book
let rec createActivities(hl: (string * Nat * Nat) list): Activity list =
match hl with
| [] -> []
| x::xs -> ....
以下是输入内容:
createActivities([
"The Hobbit" , 304N, 0N
"The Fellowship of the Ring", 228N, 50N
"The Name of the Wind" , 662N, 0N
"The Emoji Movie" , 86N , 1024N
"The Hobbit" , 164N, 9001N
"The Fellowship of the Ring", 700N, 0N
结果:
[
Read { bookName = "The Hobbit"; pages = 304N }
Watch { movieName = "The Fellowship of the Ring"; duration = 228N; fileSize = 50N }
Read { bookName = "The Name of the Wind"; pages = 662N }
Watch { movieName = "The Emoji Movie"; duration = 86N; fileSize = 1024N }
Watch { movieName = "The Hobbit"; duration = 164N; fileSize = 9001N }
Read { bookName = "The Fellowship of the Ring"; pages = 700N }
]
答案 0 :(得分:2)
F#中的match表达式可以非常高级,在match表达式的各个部分中都有子匹配。例如,您的匹配表达式中的x::xs
大小写可以变成(name, duration, filesize) :: xs
。并且,如果您为其中之一指定一个值,则只有当元组的那一部分具有该值时,它才会匹配。考虑到这一点,我将您的匹配表达式写成这样:
let rec createActivities(hl: (string * Nat * Nat) list): Activity list =
match hl with
| [] -> []
| (name, pages, 0N) :: xs -> Read { bookName = name; pages = pages } :: createActivities xs
| (name, duration, fileSize) :: xs -> Watch { movieName = name; duration = duration; fileSize = fileSize } :: createActivities xs
此方法的工作原理是match
个案例将按从上到下的顺序进行处理,并使用第一个匹配的案例。因此,如果将元组作为0N
作为其第三元素,则将使用第二个匹配情况,否则将使用第三个匹配情况。因此match表达式可以保持非常简单和简洁。
答案 1 :(得分:0)
我可以这样解决问题。感谢您的帮助。
let rec createActivities(hl: (string * Nat * Nat) list): Activity list =
match hl with
| [] -> []
| (name, pagesorduration, Size) :: xs ->
if Size = 0N then Read { bookName = name; pages = pagesorduration } :: createActivities(xs)
else Watch { movieName = name; duration = pagesorduration; fileSize = Size } :: createActivities xs