1

我正在使用 Haskell openGL 绑定来尝试制作粒子生成器。我想将有关粒子的信息存储在记录中,然后我可以传入字段并在适当时更新它们。

因此记录中的位置存储为:

data Particle = Particle { pos :: Vertex2 GLfloat }

并设置如下:

Particle { pos = Vertex2 1 (0::GLfloat) }

然后我传入粒子并尝试像这样检索值:

drawParticle :: Particle -> IO ()
drawParticle part = 
    (pos part) >>= \(Vertex2 x y) ->
    print x

我得到的错误:

Couldn't match type `Vertex2' with `IO'
Expected type: IO GLfloat
  Actual type: Vertex2 GLfloat
In the return type of a call of `pos'
In the first argument of `(>>=)', namely `(pos part)'
In the expression: (pos part) >>= \ (Vertex2 x y) -> print x

我对数据类型 Vertex2 以及为什么必须用单个 GLfloat 而不是两个声明它感到有些困惑。如何从数据类型 Vertex2 GLfloat 中提取数字?(这就是我如何将 Vertex2 1 (0::GLfloat) 提取为 x = 1.0,y = 0.0?

4

1 回答 1

3

要回答您的问题:

  • 可以将 Vertex2 定义为两种类型,以允许 X 具有一种类型而 Y 具有另一种类型,例如data Vertex2 xtype ytype = Vertex2 xtype ytype. 但是,为 X 和 Y 设置两种不同的类型通常不是一个好主意,因此将其定义为:data Vertex2 sametype = Vertex2 sametype sametype保存问题。

  • 由于您已在 Particle 声明中显式键入 Vertex2,因此无需键入您列出的表达式。Particle { pos = Vertex2 1 0 }应该够了。(或:)Particle (Vertex2 1 0)

  • 您会收到编译错误,因为您不需要单子绑定。 part有 type Particle, not IO Particle,所以你不需要 bind 来获取值。你可以写:

    drawParticle part = let Vertex2 x y = pos part in print x

或者:

drawParticle part = do
    let Vertex2 x y = pos part
    print x

(注意 let 的两种不同形式,取决于它是否在一个do块中;当我刚开始时,这让我很困惑。)

于 2013-10-01T11:04:46.357 回答