问题标签 [monad-transformers]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1066 浏览

haskell - 使用 monad 编写更优雅代码的技巧?

我终于掌握了如何使用单子(不知道我是否理解它们......),但我的代码从来都不是很优雅。我想是因为缺乏对所有这些功能如何Control.Monad真正提供帮助的把握。因此,我认为使用 state monad 在特定代码段中询问有关此问题的提示会很好。

代码的目标是计算多种随机游走,这是我在更复杂的事情之前尝试做的事情。问题是我同时有两个有状态的计算,我想知道如何优雅地组合它们:

  1. 更新随机数生成器的函数是某种类型Seed -> (DeltaPosition, Seed)
  2. 更新随机游走器位置的函数是某种类型的DeltaPosition -> Position -> (Log, Position)Log我可以通过某种方式报告随机游走器的当前位置)。

我所做的是这样的:

我有一个函数来组成这两个有状态的计算:

然后我把它变成一个组成状态的函数:

然后我有一个最简单的东西,例如,一个随机游走器,它只会将一个随机数加到它的当前位置:

以及重复执行此操作的功能:

然后,如果我将其加载ghci并运行:

我得到了我想要的,这是随机游走者所占据的位置列表。但是......我觉得必须有一种更优雅的方式来做到这一点。我有两个问题:

  1. 我可以使用来自的聪明函数以更“单子”的方式重写这些函数Control.Monad吗?

  2. 有没有可以使用这样的组合状态的通用模式?这是否与单子变压器或类似的东西有关?

0 投票
3 回答
484 浏览

list - 为什么我的代码使用 List 包中的一元列表这么慢?

上周,用户 Masse 提出了一个关于在 Haskell 目录中递归列出文件的问题。我的第一个想法是尝试使用List中的单子列表,以避免在打印开始之前在内存中构建整个列表。我实现了如下:

这很好用,因为它立即开始打印并且使用很少的内存。FilePath -> IO [FilePath]不幸的是,它也比同类版本慢了几十倍。

我究竟做错了什么?我从来没有在这样的玩具示例之外使用过这个ListListT,所以我不知道会有什么样的性能,但是 30 秒(相对于几分之一秒)来处理一个包含 ~40,000 个文件的目录似乎太多了减缓。

0 投票
3 回答
21996 浏览

haskell - Haskell:提升与提升IO

应该在什么情况下liftIO使用?当我使用ErrorT String IO时,该lift功能可以将 IO 操作提升为ErrorT,因此liftIO似乎是多余的。

0 投票
6 回答
5266 浏览

haskell - How can I write a state monad that does error handling as well?

I need to write a state monad that can also support error handling. I was thinking of using the Either monad for this purpose because it can also provide details about what caused the error. I found a definition for a state monad using the Maybe monad however I am unable to modify it to use Either, instead of Maybe. Here's the code:

0 投票
3 回答
1995 浏览

haskell - 结合 StateT 和 State monad

可以说我有一个功能

和一个功能:

我想在它们之间使用fg传递状态。有库函数
StateT (return . runState f)吗?或者一般来说,给定一个具有相应 monad 的 monad 转换器,是否有它的库函数?

0 投票
3 回答
568 浏览

json - 为 Text.JSON 的 Result 类型编写一个 liftIO 实例

Haskell 的 Text.JSON 库使用一种称为 Result 的抽象数据类型,它基本上是它们的 Maybe 形式,但不是 Nothing,而是 Error String。Anywho,我需要使用 liftIO 将返回 IO 事物的函数调用转换为 JSON.readJSON 实现中的 Result 事物。我是 monad 转换器的新手,似乎无法为 Result 实现 liftIO(根据 ghci,我一直在尝试构建无限类型)。

有任何想法吗?

非常感谢

编辑

对不起,我花了这么长时间来详细说明!我很感激你们的帮助。

因此,return 之前的最后一行使用 getSiteTitle 来解析位于该 url 的网站以获取其标题。但是,该函数返回一种 IO String 类型,编译器告诉我它希望它是 Result。这是不可能的吗?

再次感谢!

编辑2

我决定从我的数据类型中删除标题,稍后在 IO monad 中获取它。感谢大家的帮助!我当然从这个问题中学到了东西。

0 投票
1 回答
701 浏览

haskell - 单子转换器上下文中的单子

我很难抓住 monad 和 monad 转换器。我有以下人为的示例(不可编译):

如果我将 readEither 的功能复制到 readEitherT,它可以工作,但我有一种唠叨的感觉,我可以利用现有 readEither 函数的强大功能,但我不知道如何。如果我尝试在 readEitherT 函数中提升 readEither,它会将其提升到ErrorT String IO (Either String Int)应有的状态。但我应该以某种方式得到它ErrorT String IO Int

如果我走错了方向,那么处理需要 IO(或其他 monad)并从 monadic 上下文中调用的错误的正确方法是什么(请参阅foo示例中的函数)

编辑: 显然不清楚我想要做什么。也许以下函数描述了我想知道的内容和原因

这可行,但由于绑定仍然很难看。这比以前的有大小写检查的版本要清楚得多。这是推荐的方法吗?

0 投票
3 回答
622 浏览

haskell - 是否/应该将函数包装到 monad 转换器中被视为不好的做法?

假设我们想要使用ReaderT [(a,b)]monad Maybe,然后我们想要在列表中进行查找。

现在,一个简单且不常见的方法是:

第一种可能性

但是,这似乎确实断言了有关 ReaderT 转换器如何工作的一些不平凡的事情。查看 Control.Monad.Reader 的源代码,很明显这很好用。但我还没有阅读任何支持这一点的文档。但是我们也可以这样写 find:

第二种可能性

类似的想法也适用于包装MaybeT,StateT和. 通常我会写类似于第一个示例的内容,但大多数情况下,如何编写类似于第二个示例真的很明显,您甚至可能会说它更具可读性。所以我的问题是:像第一个例子这样的代码应该被认为是坏的吗?StateReader

0 投票
1 回答
854 浏览

monads - 为什么在编写新的 Monad Transformers 时使用样板

这部分http://book.realworldhaskell.org/read/monad-transformers.html#id659032来自《Real World Haskell》一书,建议在编写新的 Monad Transformer 时,我们必须手动派生 、 等MonadState的实例。MonadIO

但我尝试了以下并编译。为什么不在图书馆做呢?

假设我有MaybeT单子变压器:

那么一旦我们知道这t是 aMonadTrans并且m是 a Monad,为什么不能像这样自动导出其他所有内容?

作者的意思是我们必须为每个新的手动执行此操作,MonadTrans否则我误解了他的意思?

非常感谢你 :)

0 投票
2 回答
553 浏览

haskell - Haskell 最佳实践:在 Haskeline 中提前终止

我正在使用Haskeline包,我想在执行任何操作之前从命令行连续获取三个字符串,并且我想出了对我来说似乎是一个很好的解决方案。但我确信可能有更好的方法来做到这一点。我正在寻找使用 Haskeline 包时的最佳实践。请评估以下示例代码的优点:

如您所见,它完成了提前终止的任务,但看起来还是有点恶心。我正在考虑尝试将 notNothing 和 getInputLine 转换为一行,例如:

我认为这看起来并不那么糟糕。我认为这是非常清晰和简洁的(虽然它没有类型检查,所以我必须编写一个版本)。

然而,这是我想出的最好的,我的问题最终是:你将如何改进这段代码,使其更整洁、更易读?我什至走在正确的轨道上吗?

编辑:如果你的守卫不是 'a /= Nothing' 那么我刚刚发现的一个很好的辅助函数是:

因为那时你可以写(如luqui建议的那样):

这很酷。但是,如果您只匹配 Nothing 那么 TomMD 的答案会更好。