【问题标题】:difficulty returning moderately complex F# type signature难以返回中等复杂的 F# 类型签名
【发布时间】:2011-05-15 20:34:13
【问题描述】:

我已经定义了 F# Tree 和 Stack 类型,在 Stack 上有一个 pop 成员。我无法在 pop 的结果上获得正确的类型签名。在我尝试使用 pop 之前,这是我的代码:

type Tree<'a> =
    | Tree of 'a * 'a Tree * Tree<'a>
    | Node of 'a 
    | None

type 'a Stack =
    | EmptyStack 
    | Stack of 'a * 'a Stack 
    member x.pop = function
        | EmptyStack -> failwith "Empty stack"
        | Stack(hd, tl) -> (hd:'a), (tl:Stack<_>)

let myTree = Tree("A", Tree("B", Node("D"), None), Tree("C", Tree("E", None, Node("G")),  Tree("F", Node("H"), Node("J"))))

let myStack = Stack((myTree, 1), Stack.EmptyStack)

现在我尝试了各种方法来返回 pop,每种方法都会引发不同类型的签名错误:

let (tree, level), z = myStack.pop

抛出: 标准输入(22,24):错误 FS0001:此表达式应具有类型 ('a * 'b) * 'c 但这里有类型 (Tree * int) Stack -> (Tree * int) * (Tree * int) Stack

//let (tree:Tree<_>, level:int), z:Stack<Tree<_>*int> = myStack.pop
let (tree:Tree<_>, level:int), z:Stack<'a> = myStack.pop
//let (tree:Tree<'a>, level:int), _ = myStack.pop
//let (tree:Tree<string>, level:int), z:Stack<Tree<string>*int> = myStack.pop

上面未注释的尝试抛出: 标准输入(16,46):错误 FS0001:此表达式应具有类型 (树 * int) * 'c 但这里有类型 '一个堆栈

【问题讨论】:

    标签: f#


    【解决方案1】:

    问题是 pop 这里是一个带一个参数的实例方法(由于function),但你希望它是一个带零参数(即单位)的实例方法,比如

    type 'a Stack =
        | EmptyStack 
        | Stack of 'a * 'a Stack 
        member x.pop() =
            match x with
            | EmptyStack -> failwith "Empty stack"
            | Stack(hd, tl) -> (hd:'a), (tl:Stack<_>)
    

    然后像这样称呼它

    let (tree,level), z = myStack.pop()
    

    [编辑]

    但实际上,由于Stack 在这里是不可变的,所以将pop 实现为实例成员并没有什么意义,因为那时它真的更像是peek。因此,您可能希望将其实现为伴随模块中的函数(或 / 以及作为 Stack 的静态成员以与其他 .NET 语言兼容):

    type 'a Stack = \\'
        | EmptyStack 
        | Stack of 'a * 'a Stack 
    
    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
    module Stack =
        let pop = function
            | EmptyStack -> failwith "Empty stack"
            | Stack(hd, tl) -> (hd:'a), (tl:Stack<_>)
    

    然后这样称呼它

    let (tree, level), z = Stack.pop myStack
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-27
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      相关资源
      最近更新 更多