我transformers在最近的博客文章中写过,有人问"人们使用Control.Applicative.Lift做什么?" 我不能回答这个问题,所以我呼应问题StackOverflow的-什么是 Control.Applicative.Lift干什么用的?
我在包中看到了一个使用它的例子,但我似乎完全无法解析它的作用.有没有人知道野外任何其他的例子?
可以为FreeT/ProgramT创建的monad变换器提供类似mtl的机制吗?
我对历史的理解如下.曾几何时,monad变压器被发明了.然后人们开始在另一个上堆叠monad变换器,然后发现插入lift到处都很烦人.然后有几个人发明了monad类,所以我们可以ask :: m r在任何monad中m这样做MonadReader r m.这可以通过让每个monad类穿透每个monad变换器来实现
(Monoid w, MonadState s m) => MonadState s (WriterT w m)
MonadWriter w m => MonadWriter w (StateT s m)
你需要为每对monad变换器提供这样的实例声明对,所以当有n个 monad变换器时,你需要n ^ 2个成本.然而,这不是一个大问题,因为人们将主要使用预定义的monad并且很少创建自己的monad.到目前为止,我理解这个故事,并且在下面的问答中也详细说明:
然后我的问题是新的免费monad http://hackage.haskell.org/package/free和操作monads http://hackage.haskell.org/package/operational.它们允许我们编写自己的DSL并将其用作monad,只需将语言定义为某种代数data类型(Operational甚至不需要Functor实例).好消息是我们可以免费获得monad和monad变换器; 那么monad课怎么样?坏消息是"我们很少定义我们自己的monad变换器"的假设不再成立.
为了解这个问题,我做了两个ProgramT,让它们相互渗透;
https://github.com/nushio3/practice/blob/master/operational/exe-src/test-05.hs
该operational包不支持monad类,所以我采用了另一个实现minioperational并将其修改为我需要的工作; https://github.com/nushio3/minioperational
不过,我需要专门的实例声明
instance (Monad m, Operational ILang m) => Operational ILang (ProgramT SLang m) where
因为以下形式的一般声明会导致不可判定的实例.
instance …
在将状态与Either进行整合(幻灯片88)时,给定State分层下的模式Either,是否有建议的方法来添加另一种类型的状态,例如,通过类似的方式记录Writer?看来新的国家有现有之间的生活State和Either为了利用快速失败行为Either中flatMap.
下面是演示代码的可运行示例,调整为使用Scalaz 7.2.8在2.11.8上工作.有没有一种方法可以在现有行为的基础上干净地添加新的monad变换器,简化了重构?在Scalaz中堆叠StateT适用于堆叠,但不处理由故障快速flatMap行为创建的排序问题Either.
// Based on slide 88+ in https://speakerdeck.com/mpilquist/scalaz-state-monad
// Adjusted for Scala 2.11 (invariant A), Scalaz 7.2 (Pointed->Applicative) and Throwable on lhs of Either
object IntegratingStateAndEither {
import scalaz._
import scalaz.Scalaz._
import EitherT._
import scalaz.StateT.stateMonad
type QueryStateS[A] = State[QueryState, A]
type ET[F[_], A] = EitherT[F, Throwable, A]
type QueryStateES[A] = ET[QueryStateS, A]
object QueryStateES …Run Code Online (Sandbox Code Playgroud) 我试图OptionT结合Future[Option[T]]在for-comprehension中返回的方法.
import cats.data._
import cats.implicits._
import cats.instances.future._
for {
data <- OptionT(repo.getData(id))
...
}
Run Code Online (Sandbox Code Playgroud)
我得到的编译器错误:
could not find implicit value for parameter F cats.Functor[scala.concurrent.Future]
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
谢谢
该streaming套餐提供了一项zipsWith功能
zipsWith
:: (Monad m, Functor h)
=> (forall x y. f x -> g y -> h (x, y))
-> Stream f m r -> Stream g m r -> Stream h m r
Run Code Online (Sandbox Code Playgroud)
还有一个稍微简化的版本,
zipsWith'
:: Monad m
=> (forall x y p. (x -> y -> p) -> f x -> g y -> h p)
-> Stream f m r -> Stream g m r -> Stream h m r
Run Code Online (Sandbox Code Playgroud)
这些可以很容易地 …
特别是,我需要能够将CGI monad与IO monad结合起来,但是如何将IO monad与Maybe monad相结合的示例可能会更好......
我玩了!2用于Scala应用程序,需要从外部服务检索JSON格式的某些数据.
表演!框架允许通过将响应包装在Promise中来异步发出HTTP请求.Promise是一个monad,它包含了将来可用的值.
这很好,但在我的情况下,我从Web服务得到的是一个JSON字符串.我必须解析它,解析可能会失败.所以我必须包装我得到的任何东西Option.结果是我的许多方法都在返回Promise[Option[Whatever]].也就是说,类型的值Whatever可能稍后可用.
现在每当我必须操作这样的值时,我需要map两次.我想用以下方式处理这个问题:
Hope[A],包装一个Promise[Option[A]]map(或者我应该使用foreach和继承某些集合特征?)和flattenPromise[Option[A]]和之间提供隐式转换器Hope[A].它很容易定义map- 两个仿函数的组合也是一个仿函数 - flatten在这种情况下可以明确地完成,或者在编写monad时Option.
但是我有限的理解是我不需要重新发明这些东西:monad变换器确实存在于这种情况下.或者,好吧,所以我认为 - 我从未使用过monad变换器 - 这就是问题的关键点:
在这种情况下可以使用monad变压器吗?我将如何实际使用它们?
我正在寻找一个可用于跟踪程序进度的monad变换器.要解释如何使用它,请考虑以下代码:
procedure :: ProgressT IO ()
procedure = task "Print some lines" 3 $ do
liftIO $ putStrLn "line1"
step
task "Print a complicated line" 2 $ do
liftIO $ putStr "li"
step
liftIO $ putStrLn "ne2"
step
liftIO $ putStrLn "line3"
-- Wraps an action in a task
task :: Monad m
=> String -- Name of task
-> Int -- Number of steps to complete task
-> ProgressT m a -- Action performing the task
-> ProgressT m …Run Code Online (Sandbox Code Playgroud) monads haskell functional-programming coroutine monad-transformers
我正在努力,Data.Fresh并且Control.Monad.Trans.Fresh,正在进行中.定义用于生成新变量的接口,以及实现此接口的monad变换器.
我最初认为可以Applicative为我实现实例,FreshT v m只有Applicative m存在的唯一要求.但是,我卡住了,似乎我需要Monad m.不相信我的Haskell的福,我再转向变压器包,并且很惊讶我发现Control.Monad.Trans.State.Lazy和.Strict:
instance (Functor m, Monad m) => Applicative (StateT s m) where
pure = return
(<*>) = ap
Run Code Online (Sandbox Code Playgroud)
所以这是我的问题:是否可以使用以下实例头创建具有等效语义的实例?
instance (Applicative m) => Applicative (StateT s m) where
Run Code Online (Sandbox Code Playgroud) Monad变换器以所有标准monad(Reader,Writer,State,Cont,List等)而闻名,但这些monad变换器中的每一个都以稍微不同的方式工作.在给定具有monad实例的类型构造函数的定义的情况下,没有用于构造monad变换器的通用方法或公式.因此,不能保证根据某些任意业务要求设计的monad数据类型将具有monad变换器.有没有这样一个明确的例子?
另一个问题解释了两个monad的仿函数组合不一定是monad.另见这个问题.这些例子没有回答当前的问题 - 它们仅仅说明了没有构造单子变压器的一般方法的问题.这些例子表明,给定两个单子M和N,我们有时会发现M(N a)是单子,有时N(M a)是单子,有时也不是单子.但这既没有说明如何为M或N构造monad变换器,也没有表明它是否存在.
另一个问题的答案认为,IO单子不能有一个单子转换,因为如果它有一个IOT,我们可以申请IOT到List,然后抬起空列表(lift [])到生成的单子就必须撤消副作用的进行"早期" IO monad.这个论点是基于IOmonad"实际上执行"可能无法撤消的副作用的想法.但是,IOmonad不是显式类型构造函数.
在明确给出monad类型的每个例子中,可以以某种方式找到monad变换器, - 有时需要一定的独创性.例如,最近发现ListT存在于Haskell库中的变换器以微妙的方式发生错误,但最终通过更改定义来解决问题.ListT
没有变换器的monad的标准示例是monad,例如IO,实际上不是由显式类型构造函数定义的 - IO是库以某种方式在低级别定义的不透明"魔术"类型.很明显,无法将IO纯函数赋予monad实例定义为显式类型构造函数.该IO示例显示,如果我们允许monad实例包含具有不纯副作用的隐藏低级代码,则monad转换器可能无法存在.所以,让我们将注意力限制在使用纯函数实现的monad上.
似乎没有一种算法可以从monad的源代码中自动导出monad变换器.我们甚至知道这总是可能的吗?
为了让我更清楚一个monad的"明确例子"我的意思:假设我声称
type Q u v a = ((u -> (a, Maybe a)) -> v) -> u -> (a, Maybe a)
Run Code Online (Sandbox Code Playgroud)
可以有一个合法的Monad实例相对于所述类型参数 …
haskell ×7
monads ×5
scala ×3
free-monad ×2
state-monad ×2
applicative ×1
coroutine ×1
either ×1
future ×1
operational ×1
scala-cats ×1
scalaz ×1