List 如何将对象列表转换为基本数据类型?
我有一个表示原始类型的区分并集:List 如何将对象列表转换为基本数据类型?,list,f#,List,F#,我有一个表示原始类型的区分并集: type Expr = | Int of bigint | Real of float | Symbol of string | Bool of bool | List of Expr list 我正在编写一个函数list:obj list->Expr list,它将检查对象的类型,并相应地将它们转换为Expr: let rec list : (obj list -> Expr list) = function
type Expr =
| Int of bigint
| Real of float
| Symbol of string
| Bool of bool
| List of Expr list
我正在编写一个函数list:obj list->Expr list
,它将检查对象的类型,并相应地将它们转换为Expr
:
let rec list : (obj list -> Expr list) = function
| head::tail ->
match head with
| :? string as x'-> Symbol (x') :: list tail
| :? int as x'-> Int(bigint x') :: list tail
| :? bigint as x' -> Int x' :: list tail
| :? bool as x' -> Bool x' :: list tail
| :? float as x' -> Real x' :: list tail
| :? Expr as x' -> x' :: list tail
| :? list<obj> as x' -> List(list x') :: list tail
| _ -> []
let rec list:(obj list->Expr list)=函数
|头:尾->
迎头赶上
| :? 字符串形式为x'->符号(x')::列出尾部
| :? int as x'->int(bigint x')::列出尾部
| :? bigint作为x'->intx'::列出尾部
| :? bool as x'->bool x'::列出尾部
| :? 浮动为x'->实x'::列出尾部
| :? Expr为x'->x'::列出尾部
| :? 列表为x'->list(列表x')::列表尾部
| _ -> []
案例
|::?list as x'->list(list x')::在这样的嵌套列表上调用此函数时,list tail
似乎不匹配:list[1;[2;1]
这可以完美地编译,但返回一个错误,表示匹配案例不完整,它似乎正在尝试对案例进行匹配,但找不到它。我希望list
能够匹配任何类型的'a
列表,但事实并非如此我应该编写什么模式使其与任何类型的列表匹配?该函数对于非嵌套对象列表非常有效。模式匹配不完整,因为head
属于obj
类型。未涵盖的情况包括,例如null
,obj()
,1L
(64位整数),System.Version()
,System.Guid(“DAB51019-DF69-4547-BC3B-5CE06BE22A7B”)
,[1;2 |]
,等等
没有处理的案例数量是无限的,因为obj
意味着任何东西,包括自定义类型
我应该写什么样的模式来匹配任何类型的列表
您始终可以使用通配符模式
。
,但只有您知道在这种情况下会发生什么。您无法使用模式匹配来检查对象是否是具有未指定泛型参数的泛型类型的值。您可以检查它是列表
还是列表
,但它必须正好是这种类型-因此当您使用检查类型时,列表
将不匹配:?list
(您也可以编写:?list
,但编译器只会用obj
填充。)
但是,如果您只关心集合,则可以使用所有集合(列表、数组等)实现的非通用System.collections.IEnumerable
接口:
let rec list : (obj list -> Expr list) = function
| head::tail ->
match head with
| :? string as x'-> Symbol (x') :: list tail
// Other cases you're already covering
| :? float as x' -> Real x' :: list tail
| :? Expr as x' -> x' :: list tail
| :? System.Collections.IEnumerable as x' ->
// It is a collection and we can get its elements as `obj` values!
let nested = x' |> Seq.cast |> List.ofSeq |> list
List(nested) :: list tail
| _ -> []
我想您必须对这些进行一些反思——请问您为什么想要/需要这样做——我通常尝试不使用这些运行时类型checking@Carsten我正在为Mathematica的互操作编写一个DSL,它允许将不同类型的列表和嵌套列表传递给Mathematica函数。例如,Table[Power[n;2];[n;1;10]
将是F#See and中的合法语法。感谢您的回答,我已经尝试过使用通配符模式,我可以使用反射来检查x
是否确实是一个列表(或数组,或seq…等等)。但是从那一点开始,我有了x:obj
,我不知道type如何将其转换为obj列表
(这样我就可以再次将其传递到list
)@ZaidAjaj您不能将int列表
转换为obj列表
。没有继承关系。您可以通过装箱int将列表实例化为obj列表。您可以键入[box 2;box 1]
,而不是[2;1]
。但是,您可以编写一个活动模式来比较泛型类型定义(一边使用typedefof,另一边使用GetGenericTypeDefinition)。