【问题标题】:PureScript equivalent to ‘error’ from Haskell preludePureScript 相当于 Haskell prelude 中的“错误”
【发布时间】:2020-08-31 23:58:57
【问题描述】:

我是 PureScript 的新手,并试图找到“断言失败”的成语。我通常在以下情况下使用它来停止执行:

  • 我需要依赖的不变量已损坏
  • 代码的某个分支无法访问
  • 我想推迟一个表达式的实现,但希望它在运行时“快速失败”(而不仅仅是 yield undefined

在 Haskell 中,我通常会使用前奏函数 error 来处理这类事情。在 PureScript 中,我(天真地)期望能够通过抛出异常和(不安全地)丢弃效果类型来模拟 error,如下所示:

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

但这不起作用:如果我在一个大型程序中嵌入对 error 的调用,我最终会得到带有字段为 undefined(在 JavaScript 意义上)的运行时对象,而不是一个突然终止的程序只要error 被执行。函数throw 似乎做了我想做的事,但是对于上面的用例,用Effect 类型污染我的程序似乎并不合适。

我不反对 PureScript 的行为——我不能将有效的计算转换为纯计算并仍然观察效果似乎是合理的。所以我想我错过了一个技巧(或者我还没有找到的库函数)。我正在寻找的 PureScript 习语是什么?

(测试库purescript-assert提供assert功能,但它也有Effect Unit类型。)

【问题讨论】:

    标签: assertion purescript side-effects


    【解决方案1】:

    您需要的是unsafePerformEffect - 它将以透明的方式执行效果并将其结果作为纯值返回。

    error :: forall a. String -> a
    error = unsafePerformEffect <<< throw
    

    或者,也可以很容易地自己进行 FFI:

    -- PureScript
    foreign import error :: String -> a
    
    // JS (foreign module)
    exports.error = msg => throw new Error(msg)
    

    【讨论】:

    • 太棒了,谢谢!是的,研究我自己的 FFI(沿着这些思路)是我的下一步,但我很高兴听到用语言做这件事很容易。到目前为止喜欢 PureScript..
    • 还有unsafeCrashWith,也就是Fyodor 已经建议的implemented in the same way :-)
    猜你喜欢
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多