给出以下类型
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#在类型级别进行编码?
答案 0 :(得分:5)
除非你的描述遗漏了一些令它变得不可行的细节,否则有一个相当简单的编码,甚至不要求该类型是通用的:
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的倒置机制,用于流量控制。
答案 1 :(得分:3)
这是不可能的。如果要实现它,那将意味着工作流本身将包含无限的泛型序列,这在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
很容易看出,为了创建一个Workflow类,我们需要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
您在上面看到的选项类型是,您可以返回值(某些)或单位(无)
请注意,此类型的类型列表确实有一个名称,并且它以某种语言实现,称为可变参数类型。