标签: monad-transformers

使用ReaderT创建可修改的环境

我一直关注并扩展教程自己写一个方案.我有一个LispVal包含在几层monad变换器中的类型:

import qualified Data.Map as M

data LispVal   = ...
data LispError = ...

type Bindings = M.Map String (IORef LispVal)
data Env = Environment { parent :: Env, bindings :: IORef Bindings }

type IOThrowsError = ErrorT LispError IO
type EvalM = ReaderT Env IOThrowsError
Run Code Online (Sandbox Code Playgroud)

使用的想法ReaderT是,我将能够通过评估器自动传递环境(维护变量绑定),并且在使用它的地方很明显,因为会有一个调用ask.这似乎比将环境明确地作为额外参数传递更好.当我来实现continuation时,我想用ContTmonad变换器做一个类似的技巧,并避免为继续传递额外的参数.

但是,我还没有弄清楚如何通过这样做来修改环境.例如,定义新变量或设置旧变量的值.

举一个具体的例子,假设每当我评估一个if语句时,我想将变量绑定it到test子句的结果.我的第一个想法是直接修改环境:

evalIf :: [LispVal] -> EvalM LispVal
evalIf [test, consequent, alternate] = do
  result <- eval test
  bind …
Run Code Online (Sandbox Code Playgroud)

haskell monad-transformers

2
推荐指数
1
解决办法
434
查看次数

Scala简化了嵌套monad

我有一些用Lift编写的代码.基本上它的嵌套Box(类似monad to Option).如果可能的话,我想稍微简化一下.最好添加类型参数,这样可以根据需要轻松更改为字符串或双精度.这是代码

tryo(r.param("boolean parameter").map(_.toBoolean)).map(_.openOr(false)).openOr(false)
Run Code Online (Sandbox Code Playgroud)

"tryo"是辅助函数,用于捕获并在Box中包含结果,如果发生异常且r是Req对象."param"函数返回Box [String](来自请求参数).我想让它适用于Int的String等等,如果可能的话,摆脱嵌套的map/openOr(你认为在Option类型中有getOrElse).

Monad变形金刚?

monads scala monad-transformers

2
推荐指数
1
解决办法
698
查看次数

参数化也许是monad

我和Monad,ReaderT混淆了......要表现"简单吗?" 行为.

我想将测试函数散布到Maybe转换(Maybe或另一个个性化的monad)中.

确切地说,我想要避免t调用,创建某种monad(monad,我认为)

doCalculus :: (Int -> Bool) -> Int -> Maybe Int
doCalculus f a = do
  b <- t $ a + 1
  c <- t $ 2 * b
  d <- t $ a + b + c
  return d
  where t = if f n then Just n else Nothing
Run Code Online (Sandbox Code Playgroud)

test :: Int -> Bool
test n = not (n `elem` [3, 7, 9])

*Main> doCalculus test 2 …
Run Code Online (Sandbox Code Playgroud)

haskell monad-transformers

2
推荐指数
1
解决办法
199
查看次数

如何在haskell中将功能提升到变形monad?

我知道数据构造函数和run***函数,

我可以将任何函数提升到特定的MonadTrans实例.

像这样,

import Control.Monad.Trans
import Control.Monad.Trans.Maybe
import Control.Monad

liftF :: (Monad m) => (a -> b) -> MaybeT m a -> MaybeT m b
liftF f x = MaybeT $ do
       inner <- runMaybeT x
       return $ liftM f inner
Run Code Online (Sandbox Code Playgroud)

但是我怎样才能将这个liftF推广到

liftF :: (MonadTrans t, Monad m) => (a -> b) -> t m a -> t m b
Run Code Online (Sandbox Code Playgroud)

monads haskell monad-transformers

2
推荐指数
1
解决办法
927
查看次数

如果其中一个monad被包裹在monad变换器中,是否可以重用monad合成函数?

假设我有函数组成两个monad动作:

co :: Monad m => m a -> m a -> m a

您可以将其co视为更高阶函数,描述两个monadic动作如何相互合作以完成任务.

但现在我发现第一个monadic动作可能包含在monad变换器中,而第二个不是:

one :: (MonadTrans t, Monad m) => t m a

two :: Monad m => m a

但是还是想把它们组合在一起,所以我需要一个功能:

co' :: (MonadTrans t, Monad m) => t m a -> m a -> t m a

因此,第一个t m a可以m a通过将所有m原语提升到上下文中来合作t.

这里的诀窍是在co不知道mor 的实现的情况下构建t.我觉得答案是在MFunctor包中的某个地方,事实上昨天也提出了类似的问题.但是想不出什么好的,有什么想法吗?

monads haskell monad-transformers

2
推荐指数
1
解决办法
203
查看次数

我可以把这个纯函数上的IO monad丢弃吗?

作为一个新手,很难将好的问题标题表述出来.请使这个问题搜索友好=)

试图编写我的第一个"真正的"Haskell程序(即不仅是Project Euler的东西),我试图用很好的错误消息来读取和解析我的配置文件.到目前为止,我有这个:

import Prelude hiding (readFile)
import System.FilePath (FilePath)
import System.Directory (doesFileExist)
import Data.Aeson
import Control.Monad.Except
import Data.ByteString.Lazy (ByteString, readFile)

-- Type definitions without real educational value here

loadConfiguration :: FilePath ->  ExceptT String IO Configuration
loadConfiguration path = do
    fileContent     <- readConfigurationFile "C:\\Temp\\config.json"
    configuration   <- parseConfiguration fileContent
    return configuration

readConfigurationFile :: FilePath -> ExceptT String IO ByteString
readConfigurationFile path = do
    fileExists <- liftIO $ doesFileExist path
    if fileExists then do
        fileContent <- liftIO $ readFile path        
        return …
Run Code Online (Sandbox Code Playgroud)

haskell monad-transformers

2
推荐指数
1
解决办法
215
查看次数

在一些其他monad m1中绑定一个monadic值(m2 a)

今天在Coding Dojo工作,我尝试了以下方法

example :: IO ()
example = do input <- getLine
             parsed <- parseOnly parser input
             ...
Run Code Online (Sandbox Code Playgroud)

其中,parseOnly :: Parser a -> Either String a(从attoparsec课程)编译器抱怨说,Either ..没有IO ..实质上是告诉我,我混的单子.

当然这可以通过解决

             case parseOnly parser input of .. -> ..
Run Code Online (Sandbox Code Playgroud)

我想,这有点不雅观.另外我的猜测是其他人之前遇到过这个问题而且我认为解决方案与monad变换器有关,但最后一点我不能拼凑在一起.

它也让我想起了liftIO- 但这是另一种方式,我认为这解决了在一些周围的monad中发生IO动作的问题(更确切地说MonadIO- 例如在内部,Snap当一个人想要stdout在获取一些http 时打印一些东西).

更一般的这个问题似乎是针对a Monad m1和a(不同)Monad m2我该怎样做的事情

example = do a <- m1Action
             b <- m2Action
             ..
Run Code Online (Sandbox Code Playgroud)

monads haskell monad-transformers

2
推荐指数
1
解决办法
268
查看次数

为什么RWST ...不是MonadReader,MonadState,MonadWriter的实例

我刚刚发现,RWST(从transformers)不携带一个实例MonadReader,MonadStateMonadWriter.这对我来说似乎有些奇怪,因为这些实例会立即提高可用性,例如能够使用.=,或者只是普遍提高可重用性.

当然这个决定有理由吗?

haskell monad-transformers

2
推荐指数
1
解决办法
70
查看次数

如何使用StateT,ContT和ReaderT创建monad?

如何创建使用State,Cont和Reader变换器的monad?我想阅读一个环境,并更新/使用状态.但是,我还想暂停/中断动作.例如,如果满足条件,则状态保持不变.

到目前为止,我有一个使用ReaderT和StateT的monad,但我无法弄清楚如何包含ContT:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Test where
-- monads
import   Data.Functor.Identity (Identity, runIdentity)
import   Control.Monad.State
import   Control.Monad.Reader
import   Control.Monad.Cont

-- reader environment
type In = Integer

-- cont: if true then pause, else continue 
type Pause = Bool

-- state environment:
newtype StateType = StateType { s :: Integer }

newtype M r = M {_unM :: ReaderT In (ContT Pause (StateT StateType Identity)) r}
  deriving ( Functor, Applicative, Monad
           , MonadReader In
           , MonadCont   Pause
           , MonadState …
Run Code Online (Sandbox Code Playgroud)

monads continuations haskell monad-transformers

2
推荐指数
1
解决办法
344
查看次数

无法为新类型创建MonadTrans的派生实例

我有以下新类型声明。它包装了Monad堆栈变压器,堆叠了一些标准的mtl monad,例如Reader和Except。

newtype TrxDbFileBased f a = TrxDbFileBased {
        unTrxDbFileBased :: ExceptT TrxDbError (ReaderT TrxDbFileBasedEnv f) a
    } deriving (
        Functor
    ,   Applicative
    ,   Monad
    ,   MonadError TrxDbError
    ,   MonadReader TrxDbFileBasedEnv
    ,   MonadIO
    ,   MonadTrans
    )

data TrxDbFileBasedEnv = TrxDbFileBasedEnv {
        workingDirectory :: FilePath    
    } deriving (Show)

data TrxDbError = TrxDbErrorIO TrxDbFileBasedEnv IOException
                | TrxDbErrorStr TrxDbFileBasedEnv String 
                deriving (Show)
Run Code Online (Sandbox Code Playgroud)

我希望此新类型是的实例,MonadTrans但出现以下错误。

    • Can't make a derived instance of ‘MonadTrans TrxDbFileBased’
        (even with cunning GeneralizedNewtypeDeriving):
        cannot eta-reduce the representation type …
Run Code Online (Sandbox Code Playgroud)

monads haskell monad-transformers

2
推荐指数
1
解决办法
78
查看次数

标签 统计

monad-transformers ×10

haskell ×9

monads ×6

continuations ×1

scala ×1