据我所知,F# 不支持存在类型。所以,我正在寻找另一种方式来表达我的想法。
我有一个数据结构,它的内容可以用多种不同的方式来解释。在这个特定的示例中,我假设它可以被视为 int 或 real:
type Packed = (* something sensible *) unit
type PackedType = | PackedInt
| PackedReal
let undefined<'a> : 'a = failwith "undefined"
let unpackInt : Packed -> int = undefined
let unpackReal : Packed -> real = undefined
let packInt : int -> Packed = undefined
let packReal : real -> Packed = undefined
哪里real
有意义,说:
type real = int * int
let addReal : real -> real -> real = undefined
现在,我需要一个函数addPacked : PackedType -> Packed -> Packed -> Packed
。我希望它是通用的,即:
type NumberOp = [forall t] { opPack : 't -> Packed; opUnpack : Packed -> 't; opAdd : 't -> 't -> 't }
let getNumberOp (t : PackedType) =
match t with
| PackedInt -> { opPack = packInt; opUnpack = unpackInt; opAdd = (+) }
| PackedReal -> { opPack = packReal; opUnpack = unpackReal; opAdd = addReal }
let addPacked (t : PackedType) (a : Packed) (b : Packed) =
let { opPack = pack; opUnpack = unpack; opAdd = add } = getNumberOp t
pack <| add (unpack a) (unpack b)
在这里,我以NumberOp
存在主义告终。所以我在问是否有另一种方式来表达这一点。我不能改变Packed
,[un]pack*
函数和addPacked
's 类型。
我找到了这个答案。它指出有一个“众所周知的模式”,但文本很难阅读,我无法让它工作。