如果没有DataKinds,如何使值依赖于其他值?

Mar*_*nek 4 haskell data-kinds

我有一个Universe类型和一个worker类型.工人可以改变宇宙.我想要实现的是确保宇宙只能由来自该宇宙的工人(未来或过去的工人)修改.

我能做到的最好的是:

{-# 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
Run Code Online (Sandbox Code Playgroud)

如果我改为w2 = head $ _allWorkers u2,w2 = head $ _allWorkers u我得到一个编译错误,这是我想要的.

我不喜欢的是现在我有一个附加到每个宇宙的版本,我必须手动增加它.这可以用另一种不需要显式版本控制的方式完成吗?使doSomething函数返回Universe otherType类型检查器所知的otherType位置不同于t.

谢谢你的时间.

dfe*_*uer 5

一种方法是使用存在类型:

data Un = forall s. Un (Universe s)

doSomething :: Worker s -> Universe s -> Un

initialUniverse :: Un


doStep :: Un -> Un
doStep (Un u) = let w = head $ _allWorkers u
               u2 = doSomething w u
               w2 = head $ _allWorkers u2
               u3 = doSomething w2 u2
            in Un u3
Run Code Online (Sandbox Code Playgroud)