返回列表并进入刺猬状态机中的项目

时间:2019-09-29 16:49:00

标签: haskell haskell-hedgehog

我有一个状态机模型,

newtype State (v :: * -> *) = State (M.Map (Var UUID v) DataPerItem)
    deriving (Eq, Show)

然后我有一个Command gen exec [Update update],其中exec返回了UUID的列表,即类型为

exec :: action -> m [UUID]

这反过来意味着update需要这样的类型

update :: State v -> action -> Var [UUID] v -> State V

要真正更新模型,我需要将Var [UUID] v变成[Var UUID v]。我一直盯着刺猬的功能已经有一段时间了,但是什么也没跳出来……还是我又一次在想这一切错了? :)

1 个答案:

答案 0 :(得分:1)

这行不通,但是有充分的理由。

将状态机测试视为自动编写测试程序,其中每个Var a Symbolic作为程序中的绑定。

因此,想象一下我正在使用操作create :: Size -> Bufput :: Buf -> Int -> IO ()get :: Buf -> IO Int测试一个小的缓冲区。

我可以手动进行单元测试。

test :: TestT IO ()
test = do
  buf <- create 3
  put buf 5
  put buf 10
  put buf 20
  retrieved <- get buf
  retrieved === Just 5

使用适当的命令,刺猬也可以生成此准确的测试

test :: TestT IO ()
test = do
  Var 1 = create 3
  Var 2 = put (Var 1) 5
  Var 3 = put (Var 1) 10
  Var 4 = put (Var 1) 20
  Var 5 = get (Var 1)
  Var 5 === Just 5

因此,每次执行都被赋予一个变量名。

当您想要这样的东西时:

splitNames :: Var [UUID] v -> [Var UUID v]

您所要的本质上是执行列表中的每个返回都被赋予其自己的变量名。然后,程序的其余部分可以使用这些变量名。我认为最好的显示方式是:

test :: TestT IO ()
test = do
  Var 1 = returnSomeNumberOfItems
  Var 2 = Var 1 ! 0
  Var 3 = Var 1 ! 1

现在,这里的问题是我们只是不知道returnSomeNumberOfItems返回的列表有多长时间;我们还没有运行它;无法安全地执行此操作。