types - 无法识别的联合类型参数
问题描述
我在 F# 中有以下联合和辅助函数:
type ParsedItem =
| Digit of char
| Operator of char
| Alpha of char
| NotParsed of char
let private digits = ['0'..'9']@['.']
let private opers = ['!';'%';'^';'*';'(';')';'+';'=';'<';'>']
let private alphas =['A'..'Z']@['a'..'z']
let (|IsDigitChar|_|) ch =
match List.exists(fun a->a=ch) digits with
| true -> Some IsDigitChar
| _ -> None
let (|IsOperChar|_|) ch =
match List.exists(fun a->a=ch) opers with
| true -> Some IsOperChar
| _ -> None
let (|IsAlphaChar|_|) ch =
match List.exists(fun a->a=ch) alphas with
| true -> Some IsAlphaChar
| _ -> None
let parseChar ch =
match ch with
| IsDigitChar -> Digit(ch)
| IsOperChar -> Operator(ch)
| IsAlphaChar -> Alpha(ch)
| _ -> NotParsed(ch)
但在以下函数中无法识别“数字”类型:
let coalesceDigits (dgts: Digit list) =
[|for Digit d in dgts -> d|] |> string
由于编译器对参数给出以下警告(dgts: Digit list)
:
The type 'Digit' is not defined'
但是,它还在函数体中给出了以下警告:所以它Digit d
在函数体中将其识别为 a ,但在声明中没有?[|for Digit d in ...
Incomplete pattern matches on this expression. For example, the value 'Alpha (_)' may indicate a case not covered by the pattern(s).
ParsedItem
如何让编译器识别它Digit
确实是一种类型,而不必在 之外声明它ParsedItem
,或者我必须Digit
将其他类型声明为它们自己的类型,然后将它们添加到ParsedItem
如下?
type Digit = Digit of char
[...]
type ParsedItem =
| Digit of Digit
| Operator of Operator
| ... (etc)
解决方案
Digit
不是类型。
ParsedItem
是一个类型,但Digit
不是,也不是Operator
,Alpha
和NotParsed
.
使用该语法,您定义了一个 type ParsedItem
,其值可以有四种风格 - Digit
、Operator
、Alpha
或NotParsed
。
您可以ParsedItem
通过指定要创建的风味以及风味所需的任何参数来创建新的类型值(在您的情况下,所有风味都有一个char
参数),如下所示:
let item1 = Digit 'a'
let item2 = Operator 'b'
// and so on
在此示例中,item1
和item2
都是 type 的值ParsedItem
。它们不是不同类型的值。
如果你有一个 type 的值ParsedItem
,你可以通过模式匹配找出它是什么味道:
let whatIsIt item =
match item with
| Digit c -> "It's a digit!"
| Operand c -> "It's an operand!"
| Alpha c -> "It's an alpha!"
| NotParsed c -> "Not parsed :-/"
printfn "%s" (whatIsIt item1) // prints "It's a digit!"
printfn "%s" (whatIsIt item2) // prints "It's an operator!"
如果您在编写模式匹配时错过了一种风味,编译器会捕捉到您:
let whatIsIt item =
match item with
| Digit c -> "It's a digit!"
// Warning: incomplete pattern match
有了这个警告,编译器告诉你:“我看到你已经定义了如果item
碰巧要做Digit
什么,但是我应该如何处理其他三种风格?”
这也是您的代码中发生的情况:您在 上进行模式匹配Digit d
,但您没有具体说明要为其他风格做什么。
现在,我不知道您要在这里实现什么,而且您的代码有点荒谬(由于上述原因),所以我能做的最好的就是解释您对语言语法的误解。如果您详细说明您的实际目标,我可能会建议一种正确的编码方式。
推荐阅读
- python-3.x - 查找数据框中所有行的情绪分析,而不仅仅是一个
- c# - Get DHCP IP address of Raspbery Pi
- ngx-datatable - Is It possible to programmatically resize a column [ngx-datatable]
- jquery - AdminLTE 数据表未将样式应用于标签
- ruby-on-rails - 在不使用 Ruby on Rails 中的任何 gem 的情况下生成 Excel 时,单元格样式不起作用
- anylogic - Anylogic——行人图书馆
- 68000 - BTST 无法按预期工作以确定数字是否为奇数
- sql - 编辑类型的前 200 行 ... - Sql Management Studio
- go - 在map golang中使用不同的结构作为值
- protractor - 如何使用 chai/chai-smoothie 断言输入字段的值?