Skip to content

Latest commit

 

History

History
83 lines (61 loc) · 2.44 KB

CycleInDeclaration.md

File metadata and controls

83 lines (61 loc) · 2.44 KB

CycleInDeclaration Error

Example

$ spago repl

> x = x
Error found:
at  line 1, column 5 - line 1, column 9

  The value of x is undefined here, so this reference is not allowed.


See https://github.com/purescript/documentation/blob/master/errors/CycleInDeclaration.md for more information,
or to contribute content related to this error.

Cause

This error occurs when a value refers to itself, or another value in the same binding group, at a point where such a reference would be unavailable because of strict evaluation.

In the example above, it would be incorrect to generate the JavaScript

var x = x;

since then x would be undefined.

Note that cycles can also spring up in much less obvious ways, e.g. if you define one typeclass member using another.

Fix

  • Consider the problem again, keeping PureScript's strict evaluation in mind. How would you solve this problem in JavaScript, for example?
  • Sometimes you can break the cycle by strategically using eta expansion (\x -> f x instead of f) or using do-notation, which will introduce a function to the same effect because of bind.
  • You might be able to make use of the Control.Lazy module, and the fix function in particular.

Notes

Additional Examples

Mutually recursive functions:

{-
A very inneficient way to write:
zeroOrNine n = if n >= 9 then 9 else 0
-}
zeroOrNine :: Int -> Int
zeroOrNine 9 = 9
zeroOrNine n | n < 0 = 0
zeroOrNine n = again (n - 1)

again :: Int -> Int
again = zeroOrNine
{-
Fix compiler error by replacing the above line with either:
again n = zeroOrNine n
again = \n -> zeroOrNine n
-}

https://try.purescript.org/?gist=3e013405988ab9a58521412fddadca08

Type class instance for recursive data type:

data Chain a
  = End a
  | Link a (Chain a)

derive instance genericChain :: Generic (Chain a) _

-- This builds, but blows-up call stack and triggers a
-- "too much recursion error".
instance showChain :: Show a => Show (Chain a) where
  show = genericShow
{-
Fix the issue by replacing the above line with:
  show c = genericShow c
-}

https://try.purescript.org/?gist=32b78ce065d60427620cdd8d40777a1f