【问题标题】:F# type obj but I want 'aF# 输入 obj 但我想要 'a
【发布时间】:2017-09-01 02:44:29
【问题描述】:

我定义了一个类型

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

例子:

( "this" . (("is" . "a") . ( "s" . "expression")) )

是一个字符串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 -> 字符串列表

我的问题是我想要一个性别而不是像告诉我的 obj 性别。我哪里做错了?

通话就是这样 tolist (T(E("this") , E("is")));;

【问题讨论】:

    标签: list recursion f# functional-programming


    【解决方案1】:

    F# 中的string 函数具有obj -&gt; string 类型,因此它将E(x) 中的x 类型限制为obj。 (更新:比这稍微复杂一些;有关所有详细信息,请参阅this answer 的后半部分。但归结为“string 需要在编译时知道其参数的具体类型时间,以便它可以调用正确的.ToString() 方法。如果你传递一个泛型类型,它唯一可以确定工作的具体类型是obj,所以它最终会受到约束你的泛型类型为obj。”)而这反过来又将tolist函数的类型限制为sexp&lt;obj&gt;(或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)@[")"]
    

    【讨论】:

    • string 不接受obj。它是通用的,但具有静态约束。请参阅此答案的第二部分:stackoverflow.com/a/43233285/180286
    • @FyodorSoikin - 感谢您的更正。我会更新我的答案以链接到那个答案,因为你已经比我解释得更好了。
    猜你喜欢
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多