考虑:
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) 我正在阅读简单的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是进口的.双方I并Value获得Show和显示自己没有问题.它的混合ET将不会显示.我看到两种方式:
deriving Show声明ET m a(我在很多方面尝试获取了很多不同的错误消息)如何ET I Value在我的REPL中显示?
有时我需要使用几个嵌套MonadTrans.例如,我会在一个MaybeT内部ExceptT,模仿continue和break命令式编程:
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操作,这很快就会成为一种厌恶.我如何使代码更清晰,更简洁?
我知道如何使用do块内每个monad的函数.但是一旦我完成了如何运行计算并获得结果?
run :: (MonadError Error m, MonadState State m) => m Int -> Int
run = ???
Run Code Online (Sandbox Code Playgroud) 给定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)
要么我没有找到这个功能,要么解决方案完全不同.
动机:能够在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) 我有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写作翻译.我想用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) 我试图ask在do带有MonadReader约束的符号块中调用,但是我遇到了关于刚性类型的错误.据我所知,ask是为所有人定义MonadReader的吗?
bar :: MonadReader r m => m r
bar = do
i <- ask
return i
Run Code Online (Sandbox Code Playgroud)
这会返回
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 …
我在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) haskell ×9
monads ×2
state-monad ×2
free-monad ×1
ghci ×1
random ×1
scala ×1
typeclass ×1
winghci ×1