假设我有许多函数:
f :: a -> Maybe a
g :: a -> Maybe a
h :: a -> Maybe a
我想用下面的方式组成它们:如果f不返回任何东西,计算g。如果g不返回任何东西,计算h。如果它们中的任何一个只计算a,就停止链。和整个组成(h。G。f)当然应该返回a。
这与“可能单子”的典型用法相反,在这种用法中,如果没有返回任何内容,通常会停止计算。
像这样的链式计算的Haskell习惯用法是什么?
在本文档中,我们调用liftIO在eval6中执行I/O操作。为什么我们要提起这个案子?因为没有IO类可以实例化类型为。因此,对于I/O操作,我们必须调用lift向内发送命令。对于eval6,我们需要撰写四次lift来打印一些东西。这只是不方便,所以人们创建了一个新的类MonadIO,这样我们只需要调用liftIO一次,而不必计算组成lift的次数:
class (Monad m) => MonadIO m where
liftIO :: IO a -> m a
instance MonadIO IO where
liftIO = id
instance (Error e,
我目前正在处理单台变压器,并试图真正理解类型签名,我有一些困惑。让我们使用以下堆栈进行讨论:
newtype Stack s m a = Stack { runStack :: ReaderT s (StateT s IO) a }
我试图逐层查看并编写未包装的类型签名,但是被卡住了:
newtype Stack s m a = Stack {
runStack :: ReaderT s (StateT s IO) a }
-- ReaderT s m a
--
我已经编写了一个Haskell类型类,使用(a -> m _)形式的类型声明它的实例会很方便,其中m是(* -> *)类型,比如monad,而_是一个不饱和的插槽。我知道如何编写newtype X a m b = X (a -> m b),以及如何为X a m声明实例。但是,如果可能的话,我正在寻找的是使用裸的、未包装的->类型。
如果你想声明(a -> _)形式的类型的实例,那么你可以这样写:
instance Foo a ((->) a) where ...
但我不知道如何/是否可以使用(a -> m _)形式的类型。我猜我希望在实例声明中组合类型
我是haskell的新手,我有以下代码
module StateTest where
import Control.Monad.State.Lazy
tick :: State Int Int
tick = do n <- get
put (n+1)
return n
plusOne :: Int -> Int
plusOne = execState tick
main = print $ plusOne 1
我想在put (n+1)之后打印状态值,并像这样继续计算
tick = do n <- get
pu
如何让用户传递一个eventHandler,它使用一个stateMonad,但在一个单独的线程中被调用?例如,在下面的示例中,如何调用forkIO以使eventHandler能够调用操作?我是新来的Haskell,请纠正我,如果这是一个错误的api公开给用户?
data MyTypeResult a = MyTypeValue a
data MyTypeState = MyTypeState {_counter :: Int}
newtype MyType a = MyType {
unMyType :: StateT MyTypeState IO (MyTypeResult a
这个话题之前已经讨论过了,所以我链接到这里。
因此,我确信它在当时是有效的,但是时间已经改变了:)
作为一个Haskell的新手,这会让我更进一步。我已经尝试了各种解决方案来解决各种问题。
建议的解决方案
instance Show a => Show (State a) where
show (State f) = show [show i ++ " => " ++ show (f i) | i <- [0..3]]
编译器报告。
myfuncs.hs:31:11: error:
Not in scope: data constructor
我正在通过例子阅读PureScript,并了解了介绍Reader的部分。例子是这样的:
createUser :: Reader Permissions (Maybe User)
createUser = do
permissions <- ask
if hasPermission "admin" permissions
then map Just newUser
else pure Nothing
对我来说,令人困惑的是ask函数。签名是:
ask :: forall r. Reader r r
它看起来像是在稀薄的空气中创建一个读取器
当我
我觉得学习haskell的心理障碍之一是,data有时将函数定义为数据。
data Person = Person {
name :: String,
age :: Int
}
这是直观的,类似于其他语言。但在
newtype StateT s m a = StateT {
runStateT :: s -> m (a,s)
}
这基本上是将一个函数s->m (a,s)称为“数据”。
我很容易明白,在高阶函数中,“函数”确实是作为数据传递的。但是在类型定义中,使用函数来定义类型,这是相当令人惊讶的。
所以我的问题是:这会给Haskell型系统带来表现力吗?这一切背后的
我正在从多个不同的地方收集代码,并试图处理以下问题:
问题
我有一个具有以下简化类型的变压器堆栈:
action :: m (ReaderT r IO) a
我试图在不同堆栈的上下文中使用该操作,它具有不同的读取器环境:
desired :: m (ReaderT r' IO) a
我当然可以提供
f :: r' -> r
示例
things :: m (ReaderT r' IO) ()
things = do
-- ... some stuff
-- <want to use action here>
action :: m (
我想知道Haskell州monad的>>的定义。
据我猜测,它会把一种状态传递给另一种状态:
(>>) :: State s a -> State s b -> State s b
State a >> State b = State $ \x -> b $ snd ( a x )
或
State a >> State b = State $ b . snd . a
这是正确的吗?
我想在Haskell中依次组成两个monad操作,丢弃第二个操作产生的任何值,并将参数传递给两个操作。目前,我正在使用这样的一个do块:
ask = do
result <- getLine
putStrLn result
return result
我希望能写得更自由和整洁一些,所以我试了一下:
ask' = getLine <* putStrLn
但是,这甚至没有输入check,问题是没有将第一个操作的结果传递给第二个操作。我想像那样连锁操作,但不改变结果。类型应该是(a -> m b) -> (a -> m c) -> (a -&g
假设我有一个monadT:
type Wrap a = ReaderT Env ( StateT Int ( StateT Int Identity ) ) a
这里需要注意的重要一点是,一个StateT包装了另一个MonadT,并且这两个are都包装在第三个are中,即ReaderT。
为了方便起见,还提供了相应的runWrap函数:
type Env = Map.Map Char Integer
runWrap :: Env -> Int -> Int -> Wrap a -> a
runWrap env st1 st2 m = runIdentity $ eva
我已经定义了我自己的单台变压器:
data Config = Config { ... }
data State = State { ... }
newtype FooT m a = FooT {
runFoo :: ReaderT Config (StateT State m) a
} deriving (Functor, Monad, MonadReader Config, MonadState State)
我为它定义了一个MonadTrans实例。
instance MonadTrans FooT where
lift = FooT . lift . li
我对命令式编程有很好的掌握,但现在我学到了一个非常好的Haskell。
我认为,我对单数、函子和应用程序有很好的理论理解,但我需要一些实践。为了练习,我有时会从我目前的工作任务中带来一些细节。
我在应用程序上结合了一些东西
第一个问题
我有两个验证功能:
import Prelude hiding (even)
even :: Integer -> Maybe Integer
even x = if rem x 2 == 0 then Just x else Nothing
isSmall :: Integer -> Maybe Integer
isSmall x = if x
我最近决定开始使用monad转换,而不是堆叠我的monad,因为这似乎是正确的做法。不管怎么说,我以前并没有堆叠很多单子。我得到(我认为)它和lift函数背后的想法,据我理解,它充当转换的一种return (将底层monad中的一些东西放入转换的monad中)。
到目前为止,还不错,但我没有看到类似于monad转换的fmap函数。让我给你举个例子。假设我有一个定制的monad,m,并且我对它使用了一个StateT转换,因此使用StateT s m a类型而不是m (State s a)。
现在,在我的monad m中,我有一个函数来转换monadic元素(事实上,它是monad的构造函数之一,
我试图在我正在进行的Haskell项目中使用“引证-解决”包,但是我很难使用真实代码中的任何一种语言。我知道它们是单台变压器,我想我明白这意味着什么,但我似乎无法真正想出如何使用它们。表示我所要做的事情的玩具示例如下:
module Main where
import Text.EditDistance
import Text.CSL.Input.Identifier
import Text.CSL.Reference
import Control.Monad.Trans.Class
import Control.Monad.Trans.Either
main = do
putS
我对Haskell monad转换器比较熟悉,但对Scalaz (版本7)还不熟悉。我从下面的Haskell代码做了一个(我认为是)简单的翻译:
import Control.Monad.State
type Pass a = StateT String Maybe a
monadTest :: Pass String
monadTest = do
s <- get
return s
对于这段Scala代码:
import scalaz._
import Scalaz._
object StateTest {
type Pass[A] = StateT[Opti
在我们的haskell代码库中,业务逻辑与跟踪和日志记录代码交织在一起。这可能会模糊业务逻辑,并使其更难理解和调试。我正在寻找一些想法,如何减少日志记录和跟踪的代码足迹,使业务逻辑更加突出。
我们的代码目前大致如下所示:
someFunction a b cs =
withTaggedSpan tracer "TRACE_someFunction" [("arg_b", show b)] $ do
logDebug logger $ "someFunction start: " <> show (trimDownC &l
考虑下一个示例。我有一个只是一个StateT的monad MyM
{-# LANGUAGE TypeFamilies #-}
import Control.Monad.State
import Control.Monad.Reader
type MyS = Int
type MyM = StateT MyS
通常MyM是用来读写MyS状态的,所以我有如下的函数:
f1 :: (MonadState m, StateType m ~ MyS) => m ()
f1 = modify (+1)
但有时我只需要读取MyS,所以我想要MonadReader上下文而不是MonadState
f
我想在一系列不变的值中跟踪“当前”值。在Haskell中,不为每一个新的价值引入一个新的引用,最好的方法是什么?下面是一个示例:
data Person = Person {name, level, topic :: String }
deriving(Show)
dierk :: Person
dierk = Person "Dierk" "confident" "Java"
works :: Person -> String
works person = name person ++ " is " ++ le
抱歉,如果这个问题看起来有点琐碎...这不是给我的。我很高兴地写了下面的单曲:
type SB i a = ReaderT ( AlgRO i ) (State ( AlgState i ) ) a
这是一个表现良好的单元体。ReaderT是monad转换器,state是State monad,AlgRO和AlgState是在i中参数化的数据类型,分别表示可变状态和只读状态。现在,如果我想用newtype制作一个整洁的monad变压器,就像这样:
newtype SbT m i a = SbT {
runSbT:: m ( SB i a )
}
我应该如何继续?我甚至连绑定方法( Mo
我从ReaderT那里得到了Control.Monad.Reader
newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
和Action来自Database.MongoDB.Query
type Action = ReaderT MongoContext
MongoDB的查询函数如下所示:
delete :: MonadIO m => Selection -> Action m ()
我试着用Action m ()的模式来检查它是Action IO ()还是Action _ ()
像这样简单的案子
case x
我不能处理以下问题:
我有一些函数,返回foo :: a -> b -> ErrorT String IO Int
我知道它返回IO (Either String Int)。
尽管如此,我还有一个更复杂的函数,返回:
bar :: a -> b -> StateT Char (ReaderT Char (ErrorT String IO)) Int
这个函数bar调用函数foo。我要做的是:
如果foo调用throwError,那么bar也会抛出相同的错误。如果foo返回Int,bar也返回Int。
然而,由于不匹配类型,这是可能的。
我不知道如何以优雅的方式做这件
试图掌握我正在Haskell中使用WriterT和State (它是)来解决一个练习的概念。由于某些原因,我不明白,我最终使用了大量的内存和我的笔记本(只有4G Ram)停了下来。
我的第一个想法是使用严格的和周围的刘海-但这个问题仍然存在。
有人能解释我哪里出了问题吗?
下面是清理代码:
{-# LANGUAGE BangPatterns #-}
module Main where
import Control.Monad.State.Strict
import Control.Monad.Writer.Strict
main = do
let generators = (Genera