在Haskell中,如何为此函数提供正确的数字?

use*_*024 1 haskell

我是Haskell的初学者,试用GPipe.

以下代码运行正常:

shader <- compileShader $ do
  primitiveStream <- toPrimitiveStream id
  let transPrims = fmap
        (\(pos,col) -> (perspective (pi/3) 1 1 100 !* pos, col)) 
        primitiveStream
  fragmentStream <- rasterize
        (const (FrontAndBack, ViewPort (V2 0 0) (V2 500 500), DepthRange 0 1))
        transPrims
  drawContextColor (const (ContextColorOption NoBlending (V3 True True True)))
                   fragmentStream
Run Code Online (Sandbox Code Playgroud)

但是,我有2个变量windowWidth和windowHeight(都是Int类型),当我尝试这样做时:

shader <- compileShader $ do
  primitiveStream <- toPrimitiveStream id
  let transPrims = fmap
        (\(pos,col)
         -> (perspective (pi/3) (windowWidth/windowHeight) 1 100 !* pos, col))
        primitiveStream
  fragmentStream <- rasterize
        (const (FrontAndBack, ViewPort (V2 0 0) (V2 500 500), DepthRange 0 1))
        transPrims
  drawContextColor (const (ContextColorOption NoBlending (V3 True True True)))
                   fragmentStream
Run Code Online (Sandbox Code Playgroud)

我收到编译错误:

Couldn't match type ‘S V Float’ with ‘Int’
      Expected type: Shader
                       os
                       (ContextFormat RGBFloat ())
                       (PrimitiveArray Triangles (B4 Float, B3 Float))

                       (PrimitiveStream Triangles (V4 Int, V3 VFloat))
        Actual type: Shader
                       os
                       (ContextFormat RGBFloat ())
                       (PrimitiveArray Triangles (B4 Float, B3 Float))
                       (PrimitiveStream Triangles (VertexFormat (B4 Float, B3 Float)))
Run Code Online (Sandbox Code Playgroud)

想到它也许想浮动,我这样做(toFloat $ windowWidth/windowHeight):

Couldn't match type ‘Float’ with ‘S V Float’
      Expected type: VFloat
Run Code Online (Sandbox Code Playgroud)

我如何获得VFloat?

dup*_*ode 5

VFloat是...的同义词S V Float.条目上方有几行VFloat,GPipe文档解释说:

类型S x a是一个opaque类型,表示a着色器阶段中的类型值x,例如S F Float表示片段流中的浮点值.

它还告诉我们,通过下面的实例列表,有两个实例NumFractionalfor S whatever Float.该Num实例解释了为什么你可以将文字1作为S V Float参数传递.这也意味着您可以使用fromIntegral创建S V Float值,因此以下应该可以解决问题:

fromIntegral windowWidth / fromIntegral windowHeight
Run Code Online (Sandbox Code Playgroud)

(我用的是而不是简单的fromIntegral (windowWidth / windowHeight),因为正如crockeea指出,你不能使用(/)带有IntS,因为Int没有Fractional实例.)