Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 哈斯克尔:是的,州政府_Haskell_State_Yesod_Acid - Fatal编程技术网

Haskell 哈斯克尔:是的,州政府

Haskell 哈斯克尔:是的,州政府,haskell,state,yesod,acid,Haskell,State,Yesod,Acid,我正在通读一段时间的代码。然而,有些重要的部分我就是想不起来 其代码如下: data URLShort = URLShort { state :: AcidState URLStore } 出于测试目的,我在自己的应用程序中编写了如下内容: data MyApp = MyApp { state :: Int } 然后,我可以通过更改 main = warpDebug 3000 MyApp 到 然后我可以通过 mystate <- fmap state getYesod 但我没能做

我正在通读一段时间的代码。然而,有些重要的部分我就是想不起来

其代码如下:

data URLShort = URLShort { state :: AcidState URLStore }
出于测试目的,我在自己的应用程序中编写了如下内容:

data MyApp = MyApp { state :: Int }
然后,我可以通过更改

main = warpDebug 3000 MyApp

然后我可以通过

mystate <- fmap state getYesod 
但我没能做到这一点

我试图通过做一些简单的相似的例子来了解
AcidState
是如何工作的,我想既然
AcidState
将所有内容都保存在内存中,我应该也能这样做


任何关于这里发生的事情的一般性解释,以及我是如何遗漏这一点的,都将非常感激。

AcidState a数据类型并不是一个始终不变的值;它包含对内部可变数据的引用。在本例中,存储在Yesod land中的内容只是对该数据的不可变引用。更新状态时,实际上不更新基础数据类型中的值,而是更新指向它的内存。

Haskell世界中的每一个值都是不变的。然而,Haskell领域之外的很多东西并不是一成不变的;例如,当您执行
putStrLn
时,终端会改变其显示以显示新内容。
putStrLn
操作本身是一个不可变的纯值,但它描述了如何执行涉及突变的操作


还有其他一些功能也会产生执行突变的动作;如果你做了
ref,我真的不明白这一点。我认为Haskell中的所有数据都是不可变的,即使是单子,因为“do符号”只是函数代码的语法糖。如果这个数据是“秘密”可变的,那么Haskell通过假设所有内容都是不可变的,不可能不返回修改后的值(因为它会假设它是不变的)。你似乎在暗示它像“unsafePerformIO”一样工作。真的是这样吗?我已经更新了我的答案,如果你还有问题,请评论。谢谢更新的答案。后续问题:你能提供一个像“IORef”或“TVar”这样的小版本的实现吗?这样我就可以看到他们在做什么(现在看起来像是黑魔法)?我还想了解一些关于线程安全的信息,但我认为最好先通读一下您关于实现细节的回答。
IORef
是一种黑魔法。我无法提供一个实现,因为我无法说明如何实现
putStrLn
Int
。资料来源是真实的,但几乎不能提供信息;IO引用在Haskell中是基本的,所以所有内容都重定向到GHC内部。TVar的情况也一样;它使用GHC内部构件来实现软件事务性内存。谢谢,这现在更有意义了。我要试一试。
mystate <- fmap state getYesod 
data MyApp = MyApp { state :: State Int Int }
data VisitorCounter = VisitorCounter { visitorCounter :: IORef Int }
main = do
  counter <- newIORef 0
  warpDebug 3000 (VisitorCounter counter)
counter <- fmap visitorCounter getYesod
modifyIORef counter (+1)
count <- readIORef counter
-- ... display the count or something
counter <- fmap visitorCounter getYesod
count <- readTVar counter
Couldn't match expected type `GHandler sub0 Middleware t0'
            with actual type `STM a0'
In the return type of a call of `readTVar'
In a stmt of a 'do' expression: count <- readTVar counter