Haskell中的不安全函数是什么?

Haskell中的不安全函数是什么?,haskell,unsafe,Haskell,Unsafe,我相信一个不安全的函数是这样一个函数,它说它将返回某种类型的值,但实际上它可以抛出一个异常并结束执行,因此根本不返回任何值,但我不确定 或者,一个不安全的函数是一个可以返回除签名中声明的值以外的其他类型的值的函数吗?这不是弱类型函数吗 还是Haskell中的弱类型和不安全同义词 这可能是个愚蠢的问题,但我找不到一个直截了当的答案 我查看了文档,希望看到对不安全函数的引用,但没有 这篇文章讲了一些关于打破类型系统的内容,但没有具体说明是以何种方式进行的;通过异常?,通过返回错误类型的值 那么,什么

我相信一个不安全的函数是这样一个函数,它说它将返回某种类型的值,但实际上它可以抛出一个异常并结束执行,因此根本不返回任何值,但我不确定

或者,一个不安全的函数是一个可以返回除签名中声明的值以外的其他类型的值的函数吗?这不是弱类型函数吗

还是Haskell中的弱类型和不安全同义词

这可能是个愚蠢的问题,但我找不到一个直截了当的答案

我查看了文档,希望看到对不安全函数的引用,但没有

这篇文章讲了一些关于打破类型系统的内容,但没有具体说明是以何种方式进行的;通过异常?,通过返回错误类型的值


那么,什么是Haskell中的不安全函数呢?

Haskell中有几个“不安全”的概念

  • 计算该值将导致I/O。这里的主要可疑对象是
    unsafePerformIO
    。根据这个定义,惰性I/O和
    unsafeInterleaveIO
    是否应该被视为不安全,这有点争议

  • 有些东西打破了打字系统。主要嫌疑犯是
    unsafecorce
    ,但
    unsafePerformIO
    也可以这样做

  • 有些东西在不破坏打字系统的情况下破坏了记忆安全(感谢Carl提醒我)。主要嫌疑犯是
    不安全的
    数组或向量索引操作以及错误使用外部函数接口

  • 计算结果取决于评估顺序。主要嫌疑犯是
    unsafePerformIO
    ,但
    unsafeInterleaveST
    肯定也能做到

  • 求值可能导致异常或无限循环。这是一种相对温和的不安全。。。除非不是这样

  • 有些东西打破了Haskell程序员用来推理代码的惯例(“法律”)。这是否应该被视为“不安全”还有待讨论。示例:将
    seq
    应用于函数,使用
    强制
    改变函数相对于其参考实现的算术性,如果有人将
    seq
    应用于以前的部分应用程序,现在可能会出现问题(在某些情况下,这样做有很好的性能原因),编写的类实例打破了函子、应用程序、单子、可遍历等定律。期望参数满足前提条件,但不检查它们是否满足(例如,快速将升序列表变为集合或映射的函数)

  • 安全哈斯克尔 为了帮助程序员控制某些形式的不安全,Safe Haskell系统根据模块使用的导入和语言扩展将模块分为安全模块和不安全模块

    我认为你的概念1到3会被Safe Haskell认为是不安全的。它可能值得一读,因为Safe Haskell的作者们显然对安全有着深刻的思考

    而厄尔詹·约翰森

    Safe Haskell还不允许某些符合第6点的内容,例如可以绕过模块导出边界(模板Haskell、广义新类型派生)或更改导入代码行为(规则、重叠实例)的扩展

    程序员可以标记一个模块
    安全
    ,表示他们希望GHC检查它是否安全,
    不安全
    表示它不安全,或者
    可信
    ,表示作者声称尽管其实现使用了不安全的功能,但其API使用是安全的。

    来源:

    如果使用unsafe关键字注释外部导入声明,这将向编译器表明:(1)调用不会直接或间接调用另一个Haskell函数;(2)您不介意在调用期间系统中是否有任何其他正在运行的Haskell线程被阻塞


    “不安全”没有正式的定义。我相信它被用作“可以打破语言的正常规则”。看看那篇维基文章,称之为
    seq
    Unsafe有点极端。@melpomene,现在,“不安全”是一个笨拙的词,意思是“可以打破语言的正常规则”演讲者认为他们希望自己用的语言编程,但出于某种原因却不是。它过去的意思是dfeuer的1-4(绝对不是5或6).
    强制
    会影响函数的算术性吗?我希望算术性分析能看穿
    newtype
    s.@OrjanJohansen,我想我描述得不太对。与参考实现相比,它可以改变使用它的函数的算术性。
    fmap f(Identity x)=Identity(fx)
    给出了
    fmap
    arity 2。
    fmap=concurve
    给出了arity 1。因此,依赖于arity 2的人(使用shady
    seq
    )你会感到惊讶。你错过了牺牲内存安全的案例,比如向量或数组中出现的案例。回答很好。你忘了添加安全Haskell的概念。我认为你的概念1到3会被安全Haskell认为是不安全的。这可能值得一读,因为安全Haskell的作者已经清楚地对sa进行了深入思考费蒂。@GarethR,我要加上它,但这是一个倒数,因为它是保守的。