我试图弄清楚如何处理模式匹配情况,它根据匹配返回不同的类型,我知道它必须为每个分支返回相同的类型,所以我不确定处理一个“正确”的方法是什么这样的情况是:
我试图在下面举例说明我的困惑,paintArr 是一个数组,表示可以包含某种颜色或空槽的调色板。
paintArr.[i,j].color 是 Color 类型的选项,包含黑白。
模式匹配应该为每个插槽决定颜色是黑色还是白色,并将其索引添加到适当的数组中。
let sort (paintArr: Pallete) =
let black = [||]
let white = [||]
for i = 0 to 5 do
for j = 0 to 5 do
match ((Option.get (paintArr.[i,j])).color) with
| White -> Array.append white paintArr.[i,j]
| Black -> Array.append black paintArr.[i,j]
| None -> "not sure what to do here"
(black, white)
所以基本上,我认为我的问题归结为:您如何处理这样的情况,在某些情况下,我会得到一场需要我什么都不做的比赛,或者可能只是与其他情况不同的事情?
最佳答案
序言:对我来说很明显你对 F# 非常缺乏经验。如果这是真的,我建议你先阅读某种书籍或一组教程(我总是推荐 https://fsharpforfunandprofit.com/)。您正在尝试使用比初学者应该处理的更复杂的代码。
好的,现在来看看实际的答案
首先,请注意 Array.append
不会“更改”(“更新”、“修改”)数组,而是返回一个新数组 - 您给它的原始数组和新元素的串联。有了这些知识,很容易看出您的 Array.append
调用是无用的:它们会返回一些东西,但你会立即将其丢弃。
从上下文中,我了解您实际上想要做的是用它的扩展版本替换有问题的数组。为此,您需要声明您的数组 mutable
,然后使用“破坏性更新”运算符<-
:
black <- Array.append black paintArr.[i,j]
破坏性更新运算符 <-
在 F# 中相当于赋值语句 =
在类 C 语言中。
现在,如果您像这样使用破坏性更新运算符,则该表达式的结果类型将是 unit
- 一个空类型,用于表示“无值(value)”。这种类型只有一个值,写成两个括号,括号之间没有任何内容。例如:
> let x = ()
val x : unit = ()
所以要实现“所有分支的相同类型”规则,您可以让第三个分支简单地返回 unit
值,不调用任何函数:
| None -> ()
将以上所有内容应用于您的代码,我们得到:
let sort (paintArr: Pallete) =
let mutable black = [||]
let mutable white = [||]
for i = 0 to 5 do
match ((Option.get (paintArr.[i,j])).color) with
| White -> white <- Array.append white paintArr.[i,j]
| Black -> black <- Array.append black paintArr.[i,j]
| None -> ()
(black, white)
但是,请注意,这仍然无法编译,因为其中还有其他错误。首先,Option.get
仅在 paintArr.[i,j].color
时有效是 Some
值,但是当它是 None
时会崩溃.其次,即使这个函数成功了,它也会返回一个颜色,但是你试图将它与 None
进行比较。 ,这不是一种颜色。这将产生编译时错误。
目前很难推断出您实际上想要做什么,但我会尝试猜测。我会猜 paintArr.[i,j].color
是 Color option
类型, 其中 Color
是一个包含 White
的枚举, Black
,以及其他一些颜色。
如果是这样,您需要在 Option.get( ... )
上不匹配, 但在 paintArr.[i,j].color
本身,并处理三种情况:(1)当颜色为Black
时包裹在 Some
, (2) 当颜色为 White
包裹在 Some
, 和 (3) 当颜色为 None
时:
for i = 0 to 5 do
match paintArr.[i,j].color with
| Some White -> white <- Array.append white paintArr.[i,j]
| Some Black -> black <- Array.append black paintArr.[i,j]
| None -> ()
最后,我可以看到 i
的循环。 , 但是 j
在哪里?我猜你只是忘记为它添加一个循环:
for i = 0 to 5 do
for j = 0 to 5 do
match paintArr.[i,j].color with
| Some White -> white <- Array.append white paintArr.[i,j]
| Some Black -> black <- Array.append black paintArr.[i,j]
| None -> ()
关于types - F#在模式匹配中返回不同的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48157513/