Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.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 帮助阅读monad_Haskell_Monads - Fatal编程技术网

Haskell 帮助阅读monad

Haskell 帮助阅读monad,haskell,monads,Haskell,Monads,我是haskell的新手,我必须编写一个程序上下文感知,所以我想我可以使用Reader Monad来保持从文件读取的上下文,我知道如何读取文件,将内容放入元组列表中,比如[([Char],[Char]),但是我不知道如何实现Reader Monad,以便在不使用命令式风格的情况下使程序的所有组件都可以使用环境,特别是我不知道如何设置和使用环境,据我所知,我应该将它作为参数提供给所有需要runReader函数env环境的函数,但我很困惑,有人能给我一些指示或一个好的教程吗?提前感谢使用任何“正常”

我是haskell的新手,我必须编写一个程序上下文感知,所以我想我可以使用Reader Monad来保持从文件读取的上下文,我知道如何读取文件,将内容放入元组列表中,比如[([Char],[Char]),但是我不知道如何实现Reader Monad,以便在不使用命令式风格的情况下使程序的所有组件都可以使用环境,特别是我不知道如何设置和使用环境,据我所知,我应该将它作为参数提供给所有需要runReader函数env环境的函数,但我很困惑,有人能给我一些指示或一个好的教程吗?提前感谢

使用任何“正常”单子的基本方案[0]几乎完全相同。基本上:

  • 编写返回一元类型值的函数,如果愿意,可以使用
    do
    表示法,就像编写
    IO
    函数,如
    main
  • 使用您正在使用的monad的任何特定函数
  • 使用标准规则相互调用这些函数:

    • 使用
      从同一个monad绑定一个值这是IMHO最好的monad资源-,这是它的一部分。

      我认为,如果您看看如何在不使用Reader的情况下解决这个问题,然后比较翻译后的版本,这是最简单的。下面是我正在开发的一个程序中的一个精简示例,其中环境是一组用于更新显示的回调函数。它稍微复杂一点,因为它使用ReaderT而不是Reader,但一切都以基本相同的方式工作

      runProcess :: Env -> State -> Action -> IO State
      runProcess env state action = do
        newstate <- processAction state action
        let ufunc = mainUFunc env              -- get the callback to update the display
        ufunc newstate                         -- update the display
        return newstate
      
      此时,程序的主循环基本上是:

      loop :: State -> ReaderT Env IO ()
      loop = do
        action <- liftIO getAction
        if action == EndLoop
          then return ()
          else do
            st' <- processActionR st action
            loop st'
      
      mainLoop :: IO ()
      mainLoop = do
        env <- setUpCallbacks
        let st = initState
        runReaderT $ loop st
      
      loop::State->ReaderT Env IO()
      循环=do
      
      操作您确定首先需要
      读卡器
      ?“使环境对所有组件都可用”通常不是用Haskell编写代码的最佳方式。你能更详细地描述一下你正在做的任务吗?@Travis Brown:如果你有大量基本上是静态的数据,就像整个程序中许多地方所需要的那样,这些数据只有在运行时才可用,例如,通过加载数据文件。例如,想象一个程序,当程序启动时,所有文本都被本地化并从资源文件加载。事实上,如果我觉得有什么可疑之处,那就是类型
      [([Char],[Char])]
      。知道这是一个环境,它听起来像一个字符串字典,至少应该是一个
      Data.Map.Map string
      ,如果不是像可爱的字符串这样更迷人的东西的话。回答特拉维斯:我在一个缓存服务器上工作,它根据上下文以不同的方式运行,在我的例子中,上下文是一个file.txt,可以在服务器工作时修改。读过一些关于reader monad和writer monad的文章后,我认为reader monad可能有助于管理环境,writer monad有助于缓存,但我不确定,因此我向论坛征求了建议,现在我将检查什么是bytestring trie,bind
      >=
      在哪里起作用?@cmcdragokai:它用于翻译
      do
      块。类似于
      x>=\x->
      的行,其中lambda的主体是
      do
      块的其余部分(翻译版本)。
      runProcess :: Env -> State -> Action -> IO State
      runProcess env state action = do
        newstate <- processAction state action
        let ufunc = mainUFunc env              -- get the callback to update the display
        ufunc newstate                         -- update the display
        return newstate
      
      runProcessR :: State -> Action -> ReaderT Env IO State
      runProcessR state action = do
        newstate <- lift $ processAction state action
        env <- ask                              -- get the environment from the reader
        liftIO $ (mainUFunc env) newstate       -- updating is in IO; it needs to be lifted
        return newstate
      
      loop :: State -> ReaderT Env IO ()
      loop = do
        action <- liftIO getAction
        if action == EndLoop
          then return ()
          else do
            st' <- processActionR st action
            loop st'
      
      mainLoop :: IO ()
      mainLoop = do
        env <- setUpCallbacks
        let st = initState
        runReaderT $ loop st