F#type obj但我想'a

时间:2017-04-06 07:48:50

标签: list recursion f# functional-programming

我定义了一个类型

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

示例:

(“this”。((“is”。“a”)。(“s”。“expression”)))

是一个字符串的性别。

((1.5).2)

是int的性别。

我创建了一个函数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 - &gt;字符串列表

我的问题是,我想要'一个性别而不是像对象一样告诉我。我做错了什么?

电话就是这样 tolist(T(E(“this”),E(“is”)));;

1 个答案:

答案 0 :(得分:5)

F#中的string函数的类型为obj -> string,因此它会将xE(x)的类型限制为obj 。 (更新:它稍微复杂一些;请查看this answer的后半部分了解所有细节。但它归结为&#34; string需要在编译时知道其参数的具体类型,以便它可以调用正确的.ToString()方法。如果你传递一个泛型类型,唯一的具体类型可以是某些工作时间为obj,因此最终会将您的通用类型限制为obj。&#34;)反过来,这会限制您的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)@[")"]