我定义了一个类型
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”)));;
答案 0 :(得分:5)
F#中的string
函数的类型为obj -> string
,因此它会将x
中E(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)@[")"]