1

这是我的示例代码。我一直无法弄清楚如何使我的Statesum-type 递归,同时仍然允许它在其他地方像 sum-type 一样使用。我的StateMachine类型也是如此。

let State =
      < Task : { Comment : Text, Resource : Text, End : Bool }
      | Map : { Comment : Text, Iterator : StateMachine }
      | Parallel : { Comment : Text, Branch : List State }
      >

let StateMachine
    : Type
    = { Comment : Optional Text
      , StartAt : Text
      , States : List { mapKey : Text, mapValue : State }
      }

let test
    : StateMachine
    = { Comment = Some "A simple minimal example"
      , StartAt = "Hello World"
      , States =
        [ { mapKey = "Hello World"
          , mapValue =
              State.Task { Type = "Task", Resource = "Test", End = True }
          }
        ]
      }

in  test

是否有一种合理的方法可以做到这一点,不会增加代码大小并使最终用户导入和使用的类型符合人体工程学?如果从示例中看不出来,我正在尝试对状态机进行模式化。

我尝试了以下方法,但我收到“不是记录或联合”错误State.Task

let State
    : Type
    =   ∀(_State : Type)
      → ∀(Task : { Type : Text, Resource : Text, End : Bool })
      → ∀(Map : { Type : Text, Iterator : _State })
      → _Stat
4

1 回答 1

1

首先,我相信您要说的类型是:

let State
    : Type
    = ∀(State : Type) →
      ∀(Task : { Type : Text, Resource : Text, End : Bool } → State) →
      ∀(Map : { Type : Text, Iterator : State } → State) →
        State

in  State

要回答您的问题,您可以获得的最接近递归联合类型的是这种等效表示:

let State
    : Type
    = ∀(State : Type) →
      ( < Task : { Type : Text, Resource : Text, End : Bool }
        | Map : { Type : Text, Iterator : State }
        > →
          State
      ) →
        State

in  State

...但是您不会免费获得联合构造函数,因此无论如何我都不建议使用后一种表示形式。

对于任何一种方法,您都必须创建与构造函数行为方式相同的函数;该语言不会像为非递归联合类型那样为您生成它们。

我将说明如何为第一种类型编写构造函数,因为这是我推荐使用的表示:

let Types =
      let Task = { Type : Text, Resource : Text, End : Bool }

      let Map = λ(State : Type) → { Type : Text, Iterator : State }

      let State
          : Type
          = ∀(State : Type) →
            ∀(Task : Task → State) →
            ∀(Map : Map State → State) →
              State

      in  { Task, Map, State }

let -- Record of constructors similar to what you would get from a union type
    State =
      let Task
          : Types.Task → Types.State
          = λ(x : Types.Task) →
            λ(State : Type) →
            λ(Task : Types.Task → State) →
            λ(Map : Types.Map State → State) →
              Task x

      let Map
          : Types.Map Types.State → Types.State
          = λ(x : Types.Map Types.State) →
            λ(State : Type) →
            λ(Task : Types.Task → State) →
            λ(Map : Types.Map State → State) →
              Map (x with Iterator = x.Iterator State Task Map)

      in  { Task, Map }

in  State.Map
      { Type = "Foo"
      , Iterator = State.Task { Type = "Bar", Resource = "CPU", End = False }
      }

有关更多详细信息,请参阅:

于 2020-05-12T15:24:16.880 回答