我有一个宇宙类型和一个工人类型。工人可以改变宇宙。我想要实现的是确保宇宙只能由来自该宇宙的工人修改(而不是将来或过去)。
我能做到的最好的是:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
module Module(initialUniverse, doSomething, doStep) where
data Nat = Z | S Nat
data Universe (t :: Nat) = Universe {
_allWorkers :: [Worker t]
}
data Worker (t :: Nat) = Worker
initialUniverse :: Universe Z
initialUniverse = Universe [Worker]
doSomething :: Worker t -> Universe t -> Universe (S t)
doSomething = undefined
doStep :: Universe t -> Universe (S (S t))
doStep u = let w = head $ _allWorkers u
u2 = doSomething w u
w2 = head $ _allWorkers u2
u3 = doSomething w2 u2
in u3
如果我更改w2 = head $ _allWorkers u2
为,w2 = head $ _allWorkers u
我会收到我想要的编译错误。
我不太喜欢的是现在我有一个附加到每个宇宙的版本,我必须手动增加它。这可以以不需要显式版本控制的另一种方式完成吗?类似于让doSomething
函数返回Universe otherType
类型检查器知道otherType
的与 . 不同的地方t
。
谢谢你的时间。