I’m new to PureScript and trying to find the idiom for “assertion failure”. I use this commonly to halt execution when:
- an invariant I need to rely on is broken
- a branch of the code is unreachable
- I want to defer the implementation of an expression but want that to “fail fast” at runtime (rather than just yield
undefined
)
In Haskell I would typically use the prelude function error
for this kind of thing. In PureScript, I (naively) expected to be able to emulate error
by throwing an exception and (unsafely) casting away the effect type, as below:
module Test.Test where
import Prelude
import Effect (Effect)
import Effect.Exception (throw)
import Unsafe.Coerce (unsafeCoerce)
main :: Effect Unit
main = do
_ <- pure $ error "Doesn't fail"
error' "Fails"
error :: ∀ a . String -> a
error = unsafeCoerce <<< throw
error' :: ∀ a . String -> Effect a
error' = throw
But this doesn't work: if I embed calls to error
inside a large program, I end up with runtime objects with fields which are undefined
(in the JavaScript sense), rather than a program which terminates abruptly as soon as error
is executed. The function throw
seems to do what I want, but it doesn't seem appropriate to pollute my program with the Effect
type for the use cases above.
I don't object to PureScript's behaviour -- it seems reasonable that I can't cast an effectful computation to a pure one and still observe the effects. So I guess I'm missing a trick (or a library function that I haven't found yet). What's the PureScript idiom for what I'm looking for?
(The testing library purescript-assert
provides assert
functionality, but it too has type Effect Unit
.)