标签: unsafe-perform-io

考虑到unsafePerformIO,Haskell真的是一种纯粹的功能语言吗?

Haskell通常被引用为纯函数式语言的示例.鉴于存在,这怎么可能是合理的System.IO.Unsafe.unsafePerformIO

编辑:我认为"纯功能"意味着不可能将不纯的代码引入程序的功能部分.

haskell type-systems functional-programming referential-transparency unsafe-perform-io

44
推荐指数
2
解决办法
6974
查看次数

我滥用不安全的PerformIO吗?

为了熟悉unsafePerformIO(如何使用它以及何时使用它),我实现了一个用于生成唯一值的模块.

这就是我所拥有的:

module Unique (newUnique) where

import Data.IORef
import System.IO.Unsafe (unsafePerformIO)

-- Type to represent a unique thing.
-- Show is derived just for testing purposes.
newtype Unique = U Integer
  deriving Show

-- I believe this is the Haskell'98 derived instance, but
-- I want to be explicit, since its Eq instance is the most
-- important part of Unique.
instance Eq Unique where
  (U x) == (U y) = x == y

counter :: IORef Integer …
Run Code Online (Sandbox Code Playgroud)

haskell unsafe-perform-io

23
推荐指数
4
解决办法
6127
查看次数

unsafeDupablePerformIO 和 accursedUnutterablePerformIO 有什么区别?

我在哈斯克尔图书馆的限制区闲逛,发现了这两个邪恶的咒语:

{- System.IO.Unsafe -}
unsafeDupablePerformIO  :: IO a -> a
unsafeDupablePerformIO (IO m) = case runRW# m of (# _, a #) -> a

{- Data.ByteString.Internal -}
accursedUnutterablePerformIO :: IO a -> a
accursedUnutterablePerformIO (IO m) = case m realWorld# of (# _, r #) -> r
Run Code Online (Sandbox Code Playgroud)

然而,实际差异似乎只是在runRW#和之间($ realWorld#)。我对他们在做什么有一些基本的了解,但我没有得到使用一个而不是另一个的真正后果。有人可以解释我有什么区别吗?

io haskell unsafe unsafe-perform-io

17
推荐指数
1
解决办法
872
查看次数

一种避免常见使用unsafePerformIO的方法

我经常在Haskell代码中找到这种模式:

options :: MVar OptionRecord
options = unsafePerformIO $ newEmptyMVar

...

doSomething :: Foo -> Bar
doSomething = unsafePerformIO $ do
  opt <- readMVar options
  doSomething' where ...
Run Code Online (Sandbox Code Playgroud)

基本上,一个人有一个选项或类似的记录,最初是在程序开始时设置的.由于程序员很懒惰,他不想options在整个程序中携带记录.他定义了一个MVar保持它 - 由丑陋的使用定义unsafePerformIO.程序员确保状态只设置一次,并且在任何操作发生之前.现在程序的每个部分都必须unsafePerformIO再次使用,只是为了提取选项.

在我看来,这样的变量被认为是实用的纯粹(不要打败我).是否有一个库抽象出这个概念,并确保变量只设置一次,即在初始化之前没有调用,并且不需要写unsafeFireZeMissilesAndMakeYourCodeUglyAnd DisgustingBecauseOfThisLongFunctionName

haskell global-variables purely-functional unsafe-perform-io

16
推荐指数
3
解决办法
2375
查看次数

unsafePerformIO和FFI库初始化

我正在为C中的库创建一个FFI模块,它希望在其他任何东西之前调用一次非重入函数.这个调用是幂等的,但是有状态的,所以我可以在每个Haskell调用中调用它.但它很慢并且由于不可重入而可能导致冲突.

那么这是使用unsafePerformIO的合适时机吗?我可以将Bool包装在一个不安全的IORef或MVar中,通过忽略后续调用(全局隐藏IORef状态为False的调用)使这些初始化调用成为幂等的.

如果没有,这样做的正确方法是什么?

c haskell ffi unsafe-perform-io

12
推荐指数
1
解决办法
305
查看次数

在编译时或运行时生成随机字符串,并在程序的其余部分中使用它

最好的方法是什么?unsafePerformIO?模板Haskell?别的什么?我从来没有使用过这些,所以我不知道使用它们的许多细节.

请注意,程序将在每次运行时进行编译,因此在编译时或运行时生成字符串无关紧要.我还需要在整个代码中的大量位置使用此字符串,因此我无法以"正确"方式执行此操作并将其作为IO操作,这将需要将太多其他代码放入IO monad中.

io haskell template-haskell unsafe-perform-io

9
推荐指数
3
解决办法
3264
查看次数

如何通过隐藏"状态"更改来在类型sig中编写没有IO的haskell函数

我在haskell中编写了一个函数,它接受一些参数,如Word32,String(忽略currying)并输出IO Word32.现在,这是一个真正意义上的函数:对于相同的输入,输出将始终相同.没有副作用.函数返回IO Word32而不是Word32的原因是该函数在循环中多次更新许多32位线性反馈移位寄存器(lfsr)和其他寄存器,以便计算最终的Word32输出.

我的问题是:鉴于此函数实际上没有副作用,是否可以在函数实现中隐藏这些寄存器更新,以便该函数返回Word32而不是IO Word32?如果是这样,怎么样?

monads haskell functional-programming referential-transparency unsafe-perform-io

7
推荐指数
2
解决办法
725
查看次数

显示IO类型

我有一个数据类型,其中包含IORef作为一个重要元素.这意味着没有一种干净的方法可以使它成为show类型类的成员.这不是太糟糕,因为我print在这种类型的IO monad中有一个函数.但是在GHCi中很烦人,因为每当我返回其中一个东西时,我都会收到错误声明它无法显示.

有没有办法让IOC无论如何在IO monad中运行,使用IO动作来显示结果?如果没有,是否会对写作产生任何负面影响show a = unsafePerformIO $ print a

haskell ghci unsafe-perform-io io-monad ioref

7
推荐指数
1
解决办法
2200
查看次数

如何知道一个看似纯粹的Haskell界面何时隐藏不安全的操作?

unsafePerformIO最近一直在读,我想问你一件事.我很清楚,真正的语言应该能够与外部环境进行交互,因此unsafePerformIO有些合理.

但是,据我所知,我不知道有什么快速的方法来了解一个看似纯粹的(从类型判断)接口/库是否真的纯粹没有检查代码搜索调用unsafePerformIO(文档可以省略到提到它).我知道只有当你确定引用透明​​度得到保证时才应该使用它,但我想知道它.

haskell purely-functional unsafe-perform-io

7
推荐指数
2
解决办法
233
查看次数

如何使用 unsafePerformIO 来编写 unsafeCoerce?

众所周知,这unsafePerformIO不是类型安全的。这通常通过使用它来实现来证明unsafeCoerce

box :: IORef a
box = unsafePerformIO (newIORef undefined)
{-# NOINLINE box #-}

unsafeCoerce :: a -> b
unsafeCoerce a = unsafePerformIO $
  writeIORef box a >> readIORef box
Run Code Online (Sandbox Code Playgroud)

正如我几年前所展示的,这个实现不是线程安全的。一个线程可以写入盒子,然后另一个线程可以在第一个线程可以读取之前再次写入盒子。哎呀!如何解决这个问题?

haskell unsafe-perform-io

7
推荐指数
1
解决办法
87
查看次数