标签: monad-transformers

Monad变压器用于理解

考虑:

def xs(c: String): Option[List[Long]] = ...

val ys: Stream[Long] = ...
Run Code Online (Sandbox Code Playgroud)

现在我写一个类似的方法:

def method(oc: Option[String]): Option[Long] = for { 
    c <- oc
    list <- xs(c)
} yield{        
    for {
        first <- ys.find(list contains _)
    } yield first
}
Run Code Online (Sandbox Code Playgroud)

但当然这不会编译,因为推断类型是Option [Option [Long]].

在scala语法和标准库方面有没有办法获得Option [Long]?我知道我可以模式匹配,但是问题是否只能用于理解才能完成.


感谢tenshi的答案,这就完成了工作,但是我刚刚遇到了另一个问题的例子:

class T
class U
class A(t: String)(implicit x: T)
def getU(a: A): Option[U] = ...

def getU_2(oc: Option[String]): Option[U] = for{
   c <- oc
} yield{
   implicit val someImplicit: T = new T
   val a …
Run Code Online (Sandbox Code Playgroud)

scala monad-transformers for-comprehension

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

Haskell自制monad变压器无法在GHCi中显示自己

我正在阅读简单的monad变换器,如http://www.cs.nott.ac.uk/~nhn/MGS2006/LectureNotes/lecture03-9up.pdf中所述.

我的错误处理变换器有类型

newtype ET m a = ET (m (Maybe a))
Run Code Online (Sandbox Code Playgroud)

我已经实现了所有必要的管道,我能够将它与身份monad(在我的小沙箱中调用I)和编写/编译非平凡函数相结合.

但我无法在屏幕上打印任何结果值.消息是:

No instance for (Show (ET I Value)) arising from a use of ‘print’
Run Code Online (Sandbox Code Playgroud)

Maybe是进口的.双方IValue获得Show和显示自己没有问题.它的混合ET将不会显示.我看到两种方式:

  • 尝试插入deriving Show声明ET m a(我在很多方面尝试获取了很多不同的错误消息)
  • 根据一些网络资源的建议,用"独立的派生声明"创建一个可展示的实例 - 到目前为止没有成功.

如何ET I Value在我的REPL中显示?

haskell ghci monad-transformers winghci

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

有没有比在嵌套的`MonadTrans`中每个'IO`之前写`lift`s更好的方法?

有时我需要使用几个嵌套MonadTrans.例如,我会在一个MaybeT内部ExceptT,模仿continuebreak命令式编程:

runExceptT . forM [1..] $ \ _ -> runMaybeT $ do
    ...
    mzero   -- this mimics continue
    lift $ throwE "..."    -- this mimics break
    lift . lift $ putStrLn "Hello!"
    ...
Run Code Online (Sandbox Code Playgroud)

但是,正如上面的代码所示,每次我需要IO在这个"人工循环"中进行任何操作时,我需要lift . lift在它之前放一个丑陋的东西.想象一下,如果我有更复杂的嵌套和大量IO操作,这很快就会成为一种厌恶.我如何使代码更清晰,更简洁?

haskell monad-transformers

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

Haskell MTL:如何退出monad并获取其中的值?

我知道如何使用do块内每个monad的函数.但是一旦我完成了如何运行计算并获得结果?

run :: (MonadError Error m, MonadState State m) => m Int -> Int
run = ???
Run Code Online (Sandbox Code Playgroud)

monads haskell typeclass state-monad monad-transformers

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

monad变换器堆栈中的evalState

给定mtlmonad堆栈,例如ExceptT String (WriterT String (State s a)),如何评估内部状态monad而无需打开外部monad?

have :: ExceptT String (WriterT String (State s)) a
f    :: State s a -> a

want :: ExceptT String (WriterT String Identity) a
Run Code Online (Sandbox Code Playgroud)

我可以通过调用runExceptT后跟runWriterT并重新打包结果来实现这一点,但这似乎是完成此任务的错误方法.


就我所尝试而言,类似fmap或类似的东西将无法工作,因为monad变换器堆栈被视为一个完整的monad.我需要的是一个"拆分"monad变换器堆栈的功能,如下所示:

split :: (MonadTrans s, Monad t) => (s t) a -> s (t a)
Run Code Online (Sandbox Code Playgroud)

要么我没有找到这个功能,要么解决方案完全不同.

haskell state-monad monad-transformers

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

限制效果,如使用"Freer",使用MTL风格

动机:能够在Free/ Freer-style中控制MTL中的效果.

这个例子可能有点做作 - 想象一个带有一些基本操作的程序(使用GHC 8.2 freer-simple),

#!/usr/bin/env stack
-- stack --resolver lts-10.2 --install-ghc runghc --package freer-simple
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
import Control.Monad.Freer

data Effect next where
  ReadFilename :: String -> Effect String
  WriteOutput :: Show a => a -> Effect ()
  Computation :: Int -> Int -> Effect Int

readFilename :: Member Effect effs => String -> Eff effs String
readFilename = send …
Run Code Online (Sandbox Code Playgroud)

haskell monad-transformers free-monad

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

避免使用Monad变形金刚的孤儿实例

我有monad变换器对应我的应用程序的独立功能.

天气模块中:

class Monad m => WeatherT m where
  byCity :: String -> m WeatherData

newtype MockWeather m a = MockWeather { 
  ... 
} deriving (Functor, Applicative, Monad, MonadTrans)


instance Monad m => WeatherT (MockWeather m) where
  ...
Run Code Online (Sandbox Code Playgroud)

Counter模块中:

class Monad m => CounterT m where
  increment :: m Int
  current :: m Int

newtype MockCounter m a = MockCounter {
  ...
} deriving (Functor, Applicative, Monad, MonadTrans)

instance Monad m => CounterT (MockCounter m) where …
Run Code Online (Sandbox Code Playgroud)

haskell monad-transformers

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

印在monad里面

我在haskell写作翻译.我想用monads做到这一点.我已经创建了解析器,所以我有很多函数:: State -> MyMonad State,我可以使用bind运行我的程序.m >>= inst1 >>= inst2.一切都很好,但我不知道如何使用那个monad用我的语言创建指令print(或read).

我不想要简单但丑陋的解决方案,比如保持字符串在State内打印,最后在main中打印.(如果我在打印时有无穷大怎么办?)我无法理解来自网络的关于monad功能部分的文本.有一些解释,如"在IO Monad中包装,它非常简单",但没有任何工作示例.几乎所有的印刷教程都是关于主要的印刷.

为了更好地解释问题,我准备了最小的"解释器"示例(如下).还有State就是Int,我的单子是AutomatM说明有型:: Int -> AutomatM Int.所以可能的指令是:

inc :: Int -> AutomatM Int
inc x = return (x+1)
Run Code Online (Sandbox Code Playgroud)

我设计它就像我想象的那样简单:

import Control.Applicative
import Control.Monad (liftM, ap)
import Control.Monad.IO.Class (MonadIO(..))
import System.IO

data AutomatM a = AutomatError | Running a

instance Show a => Show (AutomatM a) where
    show (AutomatError) = "AutomatError"
    show (Running a) = "Running …
Run Code Online (Sandbox Code Playgroud)

monads haskell functional-programming monad-transformers

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

为什么我不能用MonadReader约束调用ask

我试图askdo带有MonadReader约束的符号块中调用,但是我遇到了关于刚性类型的错误.据我所知,ask是为所有人定义MonadReader的吗?

bar :: MonadReader r m => m r
bar = do
  i <- ask
  return i
Run Code Online (Sandbox Code Playgroud)

这会返回

• Couldn't match type ‘m’ with ‘ReaderT r m0’
  ‘m’ is a rigid type variable bound by
    the type signature for:
      bar :: forall r (m :: * -> *). MonadReader r m => m r
    at mem.hs:50:8
  Expected type: m r
    Actual type: ReaderT r m0 r
• In a stmt …
Run Code Online (Sandbox Code Playgroud)

haskell monad-transformers

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

如何在IO中采样RVarT

我在RVarT用随机符包裹大脑时遇到困难。就像一种心理锻炼一样,我尝试使用monad变压器Maybe x随机生成并合并到其中Maybe (x, x)

我努力做到这一点,对我来说似乎很直观

maybeRandSome :: (MaybeT RVar) Int
maybeRandSome = lift $ return 1

maybeRandNone :: (MaybeT RVar) Int
maybeRandNone = MaybeT . return $ Nothing

maybeTwoRands :: (MaybeT RVar) (Int, Int)
maybeTwoRands =
  do
    x <- maybeRandSome
    y <- maybeRandNone
    return (x, y)
Run Code Online (Sandbox Code Playgroud)

并可以在IO中进行采样

> sample $ runMaybeT maybeTwoRands
Nothing
Run Code Online (Sandbox Code Playgroud)

但是我无法弄清楚是否可以逆转:

reverseMaybeRandSome :: (RVarT Maybe) Int
reverseMaybeRandSome = lift $ Just 1

reverseMaybeRandNone :: (RVarT Maybe) Int
reverseMaybeRandNone = lift Nothing

reverseMaybeTwoRands …
Run Code Online (Sandbox Code Playgroud)

random haskell monad-transformers

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