给定以下类型
type WorkflowStep<'next, 'prev, 'cancel> =
abstract member Next : unit -> 'next
abstract member Prev : unit -> 'prev
abstract member Cancel : unit -> 'cancel
我想表达这样一个事实,即'next
、'prev
和'cancel
也应该是WorkflowStep
类型或类型unit
是否可以使用 F# 在类型级别进行编码?
除非你的描述缺少一些细节,使其不可行,否则有一个相当简单的编码,甚至不需要类型是泛型的:
type Transition =
| Step of WorkflowStep
| Done
and WorkflowStep =
abstract member Next : unit -> Transition
abstract member Prev : unit -> Transition
abstract member Cancel : unit -> Transition
其中Transition
捕获您对WorkflowStep
生成另一个步骤或单位值的要求。这为您提供了一种倒置的、类似 CPS 的流量控制机制。
这是不可能的。如果要实现这一点,则意味着工作流本身将包含无限的泛型序列,遗憾的是f#不支持该序列。
下面更详细地解释了为什么使用上面提供的工作流类型的简化版本。
//error workflow must be provided a type
type Workflow<'t when 't :> Workflow<_>> =
abstract member Next : unit -> 't
但是,当我们指定类型参数时 对于返回的工作流,现在需要应用 2 个参数。
//workflow now requires 2 parameters
type Workflow<'nextvalue, 't when t:>Workflow<'nextvalue>>
abstract member Next : unit->'t
很容易看出,为了创建一个工作流类,我们需要无限数量的泛型参数,而 f# 不支持这些参数。
一种替代方法是指定工作流类型只能处理一个工作流,如果生成代码如下所示。
type Workflow<'value> =
abstract member Next : unit -> Workflow<'value> option
abstract member Prev : unit -> Workflow<'value> option
abstract member Cancel : unit -> Workflow<'value> option
您在上面看到的选项类型是,您可以返回值(一些(或单位(无(
请注意,这种类型的类型列表确实有一个名称,它在某些语言中实现,称为可变参数类型。