List F#列表拆分,拆分
我在试着解决F#中的一个练习。我必须编写一个代码来区分一本书和一部电影,并将其作为一本书或一部电影放在列表中。它可以通过文件大小区分两者,因为书籍没有文件大小。例如,如果我放入一本书,代码必须将它作为一本书和电影添加到列表中。我将示例结果与输入链接起来。先谢谢你List F#列表拆分,拆分,list,split,f#,divide,List,Split,F#,Divide,我在试着解决F#中的一个练习。我必须编写一个代码来区分一本书和一部电影,并将其作为一本书或一部电影放在列表中。它可以通过文件大小区分两者,因为书籍没有文件大小。例如,如果我放入一本书,代码必须将它作为一本书和电影添加到列表中。我将示例结果与输入链接起来。先谢谢你 type Movie = { movieName: string duration: Nat fileSize: Nat } type Book = { bookName: string
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 }
]
F#中的匹配表达式可以非常高级,在匹配表达式的各个部分中都有子匹配。例如,匹配表达式中的x::xs
大小写可以转换为(名称、持续时间、文件大小)::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
其工作原理是,将按照从上到下的顺序处理
匹配
案例,并使用第一个匹配的案例。因此,如果元组作为0N
作为其第三个元素,则将使用第二个匹配大小写,否则将使用第三个匹配大小写。因此,匹配表达式可以保持非常简单和干净的外观。我可以这样解决问题。谢谢你的帮助
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
你能解释一下你在挣扎什么吗?我想您想用实际实现替换
createActivities
中的…
——您想在那里实现什么逻辑?我想使用递归逻辑。谢谢您的帮助。我对它进行了测试,但它在“0N”处掉了一个错误。错误:“非原始数字文本常量不能在模式匹配中使用,因为它们可以通过使用数字文字模块映射到多个不同类型。请考虑使用变量替换,并在匹配子句的末尾使用‘Time=’。”然后您需要使用F#的内置int
类型,而不是Nat
。或者,如果您确实想使用Nat
,则按照错误消息的建议执行,并使用when
子句。例如,|(名称、页面、零)::xs when zero=0N->Read{…}
多亏了你的帮助,我可以解决这个问题。我用if更改了代码。