我正在使用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而不是两个GLfloat声明它有点困惑。如何从Vertex2 GLfloat数据类型中提取数字? (那我怎么把Vertex2 1(0 :: GLfloat)提取为x = 1.0,y = 0.0?
答案 0 :(得分: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)
)。
您收到编译错误,因为您不需要monadic绑定。 part
的类型为Particle
,而不是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
块中;当我开始时,这让我很困惑。)