Open Chatanga opened 4 years ago
The culprit function with a "Bug" comment near the problematic part. If someone has any idea to fix this problem (which, by design, seems specific to this only place where GPipe creates a loop), I would be happy to hear it!
while :: forall a x. (ShaderType a x) => (a -> S x Bool) -> (a -> a) -> a -> a
while c f i = fromBase x $ while_ (c . fromBase x) (toBase x . f . fromBase x) (toBase x i)
where
x = undefined :: x
while_
:: (ShaderBase (ShaderBaseType a) x -> S x Bool)
-> (ShaderBase (ShaderBaseType a) x -> ShaderBase (ShaderBaseType a) x)
-> ShaderBase (ShaderBaseType a) x -> ShaderBase (ShaderBaseType a) x
while_ bool loopF a =
let whileM = memoizeM $ do
(lifted, decls) <- runWriterT $ shaderbaseDeclare (toBase x (errShaderType :: a))
void $ evalStateT (shaderbaseAssign a) decls
boolDecl <- tellAssignment STypeBool (unS $ bool a)
T.lift $ T.lift $ tell $ mconcat ["while(", boolDecl, "){\n" ]
let looped = loopF lifted
scopedM $ do
-- Bug: reassigning back to the same var (in decls) breaks the functional referential transparency.
void $ evalStateT (shaderbaseAssign looped) decls
loopedBoolStr <- unS $ bool looped
tellAssignment' boolDecl loopedBoolStr
T.lift $ T.lift $ tell "}\n"
return decls
in evalState (runReaderT (shaderbaseReturn (toBase x (errShaderType :: a))) whileM) 0
I've ended up with this solution to fix the issue:
See for yourself:
Working around this issue is easy, but the resulting code obviously doesn’t look right from the Haskell side.