EffWebGL
определяется следующим образом в библиотеке :
type EffWebGL eff a = Eff (webgl :: WebGl | eff) a
Это просто псевдоним для Eff
, но обратите внимание, что строка его эффекта включает в себя эффект WebGl
.
Когда компилятор пытается согласовать это в вашей функции, он выводит из использования ok
в качестве обратного вызова, что ok :: Eff (webgl | eff) a
, но, поскольку обратный вызов ok
должен иметь тот же тип, что иПри обратном вызове ошибки (из подписи makeAff
) компилятор также выводит, что err :: Eff (webgl | eff) a
и, следовательно, error >>> err :: Eff (webgl | eff) a
.Однако, поскольку error >>> err
используется в качестве параметра для runWebGL
, это означает, что error >>> err :: Eff eff a
(именно так определяется runWebGL
).Таким образом, компилятор теперь имеет две части информации, которая должна быть истинной:
(1) error >>> err :: Eff (webgl | eff) a
(2) error >>> err :: Eff eff a
И это, конечно, должно означать, что (webgl | eff) === eff
.Так что eff
является частью его собственного определения.Ака "бесконечный тип".Вот почему вы получаете сообщение об ошибке.
Теперь, чтобы исправить это, вы должны принять ваш параметр err
как Eff (webgl | eff) a
(как того требует тип makeAff
), но передать егодо runWebGL
как Eff eff a
(как того требует тип runWebGL
) - то есть строка эффекта будет расширяться при переходе от внутреннего обратного вызова к внешнему.Это должно быть совершенно безопасно, поскольку внутренний обратный вызов никогда не будет использовать этот эффект в любом случае (как указано в его типе), однако компилятор не имеет безопасного способа сделать это - что может быть одной из причин эффектастроки были пропущены в PureScript 0,12 (и это хорошо!)
Вместо этого вы должны использовать небезопасный способ из Control.Monad.Eff.Unsafe
:
unsafeCoerceEff :: forall eff1 eff2 a. Eff eff1 a -> Eff eff2 a
Простооберните сообщение об ошибке при вызове этой функции, и оно будет работать:
runWebGLAff arg = makeAff (\err ok -> runWebGL arg (unsafeCoerceEff $ error >>> err) ok)
PS Обычно я бы порекомендовал перейти на PS 0.12, но, похоже, вы не можете этого сделать, потому чтоБиблиотека WebGL не была обновлена (пока?).