Rah*_*hul 10 code-reuse haskell mixins
我在Haskell中遇到了关于建模继承的这个问题,它提醒我,我有一个更复杂的版本同样的问题.我将从那里采用这个例子,因为它比思考我自己更容易.
假设您的程序包含多种类型:
data Camera = Camera ...
data Light = SpotLight ... | DirectionalLight ...
data Object = Monster ... | Player ... | NPC ...
Run Code Online (Sandbox Code Playgroud)
现在你想要实现一些基本的物理,所以你希望它们都具有位置和速度,比如某种类型Vec3.
执行此操作的一种方法是Physical使用pos和vel函数声明类型类,并为其创建所有类型的实例.但这意味着你必须修改所有类型以包含两个Vec3s,如果你已经定义了很多很好的类型,那么这很烦人,而你只想在顶部粘合一些功能.Chris Taylor提出的基于镜头的解决方案也有同样的问题.
一个对我来说更整洁的解决方案是声明一个新类型的构造函数,
data Physical a = Physical a Vec3 Vec3
Run Code Online (Sandbox Code Playgroud)
然后你只需要执行pos,vel以及Functor实例一次,你得到所有现有的类型声明.
但是......这并不是很好.如果您现在希望能够将对象绘制为蓝色或绿色或紫色,则可能需要使用颜色执行相同操作:
data Coloured a = Coloured a Colour
Run Code Online (Sandbox Code Playgroud)
但是现在,如果你有一个Coloured Physical Camera,你必须fmap一个不同的次数取决于您是否想看看它的颜色和它的位置,或者它的焦距.和a Coloured Physical Camera应该是一样的Physical Coloured Camera,但事实并非如此.所以这不是一个优雅的解决方案.
有没有一种很好的方法可以将不同的功能集混合到Haskell中的类型中?一个简单的解决方案适用于没有语言扩展或大量样板的普通旧Haskell,这是理想的,但我也愿意学习任何与镜头相关的库,如果这是解决问题的最佳方法.
(这个关于mixins风格的代码重用的老问题似乎有关,但我担心我不完全理解这个问题或接受的解决方案.)
您是否知道元数为 2 的元组有一个Functor实例,该实例映射到第二个项目?我们可以利用它来为我们谋取利益。
data PositionAndVelocity = PositionAndVelocity Vec3 Vec3
data Colour = ...
f1 :: (PositionAndVelocity, Camera) -> ...
f2 :: (Colour, Camera) -> ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
655 次 |
| 最近记录: |