haskell - 在记录上映射身份仿函数

标签 haskell functor template-haskell

我有一个像这样的记录类型:

data VehicleState f = VehicleState
                      {
                        orientation :: f (Quaternion Double),
                        orientationRate :: f (Quaternion Double),
                        acceleration :: f (V3 (Acceleration Double)),
                        velocity :: f (V3 (Velocity Double)),
                        location :: f (Coordinate),
                        elapsedTime :: f (Time Double)
                      }
                    deriving (Show)

这很酷,因为我可以拥有 VehicleState Signal在我有各种元数据的地方,我可以有一个 VehicleState (Wire s e m ())我有netwire每个信号的语义,或者我可以有一个 VehicleState Identity我在某个时间观察到实际值。
VehicleState Identity之间来回映射有没有好办法和 VehicleState' ,由映射 runIdentity 定义在每个领域?
data VehicleState' = VehicleState'
                      {
                        orientation :: Quaternion Double,
                        orientationRate :: Quaternion Double,
                        acceleration :: V3 (Acceleration Double),
                        velocity :: V3 (Velocity Double),
                        location :: Coordinate,
                        elapsedTime :: Time Double
                      }
                    deriving (Show)

显然写一个是微不足道的,但在我的实际应用程序中实际上有几种这样的类型并且我不断添加或删除字段,所以它很乏味。

我正在编写一些模板 Haskell 来完成它,只是想知道我是否在重新发明轮子。

最佳答案

如果您不反对类型族并且不需要太多类型推断,那么您实际上可以使用单一数据类型:

import Data.Singletons.Prelude

data Record f = Record
  { x :: Apply f Int
  , y :: Apply f Bool
  , z :: Apply f String
  }

type Record' = Record IdSym0

test1 :: Record (TyCon1 Maybe)
test1 = Record (Just 3) Nothing (Just "foo")

test2 :: Record'
test2 = Record 2 False "bar"
Apply类型族在 singletons 中定义包裹。它可以应用于
该包中还定义了各种类型的函数(当然,您可以定义您的
自己的)。 IdSym0具有 Apply IdSym0 x 的属性简化为普通 x .和TyCon1具有 Apply (TyCon1 f) x 的属性减少到 f x .

正如所证明的test1test2 ,这允许您的数据类型的两个版本。但是,您需要
现在为大多数记录键入注释。

关于haskell - 在记录上映射身份仿函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24922375/

相关文章:

haskell - Haskell 声明中的感叹号是什么意思?

javascript - 如何为应用计算实现协程?

c++ - 如何将变量传递给函数对象?

haskell - Yesod 中的复合主键

Haskell:在编译时严格/评估准引用值

haskell - LiftIO、do block 和语法

multithreading - SDL-Mixer 音频在启动 Reactive-Banana 输入循环时停止

haskell - 如果某些东西不是 Haskell 中的列表

module - 理解 OCaml 中的仿函数

haskell - 如何正确地将编译时信息传递给 Template Haskell 函数?