list - F# 类型 obj 但我想要 'a

标签 list recursion f# functional-programming

我定义了一个类型

type 'a sexp =
| E of 'a
| T of ( sexp<'a> * sexp<'a> );;

示例:

( "这个". (("是". "a") . ( "s". "表达式")) )

是字符串的 sexp。

( ( 1 . 5 ) . 2 )

是 int 的 sexp。

<小时/>

我创建了一个函数 tolist,给定一个表达式,返回一个具有以下格式的列表。

let rec tolist expr =
match expr with
| Null -> [" "]
| E(x) -> [string x]
| T(l,r) -> 
    let l = tolist l
    let r = tolist r
    ["("]@(l)@[" . "]@(r)@[")"];;

val tolist : expr:obj sexp -> 字符串列表

我的问题是我想要“a sexp”,而不是像告诉我的那样“obj sexp”。我哪里做错了?

调用就是这样 tolist (T(E("this") , E("is")));;

最佳答案

string F# 中的函数的类型为 obj -> string ,所以它限制了 x 的类型在你的E(x)成为obj 。 (更新:比这稍微复杂一些;有关所有详细信息,请参阅 this answer 的后半部分。但它归结为“string 需要在编译时知道其参数的具体类型时间,这样它就可以调用正确的 .ToString() 方法。如果你向它传递一个泛型类型,那么它可以确定唯一可以工作的具体类型是 obj ,所以它最终会受到限制你的泛型类型为 obj 。”)而这反过来又限制了你的 tolist 的类型函数为sexp<obj> (或obj sexp——相同类型,不同的书写方式)。

如果替换string调用 sprintf "%A"相反,你的函数将是适当通用的。例如,您希望代码如下所示:

type 'a sexp =
| E of 'a
| T of ( sexp<'a> * sexp<'a> )

let rec tolist expr =
    match expr with
    | Null -> [" "]
    | E(x) -> [sprintf "%A" x]
    | T(l,r) -> 
        let l = tolist l
        let r = tolist r
        ["("]@(l)@[" . "]@(r)@[")"]

关于list - F# 类型 obj 但我想要 'a,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43248914/

相关文章:

python - 在运行时将文件中的每个段落读取到多个列表中

c# - F#:将 FSharpRef 转换为 C# 对象引用

F# - 损坏 "then"

list - Prolog:具有元素总和 S 的 k 个元素的排列

android - Jetpack compose 中的 [NestedScrollView + RecyclerView] 或 [Nested RecyclerView (Recycler inside another recycler) 相当于什么

java - 链接列表的 get 方法不起作用...不兼容的类型

Python:从嵌套字典和列表中递归提取注释树

kotlin - 我如何让这个序列变得懒惰?

list - 有人可以帮忙解释一下这个复制功能的工作原理吗?

f# - "Ordered power set"/"Graph coloring"套