I’m new to PureScript and trying to find the idiom for “assertion failure”. I use this commonly to halt execution when:
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
.)
What you need is unsafePerformEffect
- it will execute the effect in a transparent way and return its result as a pure value.
error :: forall a. String -> a
error = unsafePerformEffect <<< throw
Or, alternatively, it's very easy to FFI your own:
-- PureScript
foreign import error :: String -> a
// JS (foreign module)
exports.error = msg => throw new Error(msg)