小编trp*_*pnd的帖子

组合多个状态/读取器单子的最佳方式?

我正在编写一个项目,涉及组成多个堆栈StateTReaderT单子:

newtype FooT m a = FooT { unFooT :: (StateT State1 (ReaderT Reader1 m)) a }

newtype BarT m a = BarT { unBarT :: (StateT State2 (ReaderT Reader2 m)) a }
Run Code Online (Sandbox Code Playgroud)

然后,我基本上只是运行所有内容FooT (BarT m)并根据需要提升到适当的 monad。我用来lens与各种状态/阅读器类型进行交互:

foo :: Monad m => FooT m ()
foo = do
  field1 .= ... -- where field1 is a lens into State1
  ...
Run Code Online (Sandbox Code Playgroud)

然而,当我添加更多StateT+ReaderT变压器时,这种方法变得丑陋(并且似乎可能会产生一些性能成本)。

到目前为止,我唯一的想法是将以下状态结合起来:

newtype BazT m a = BazT …
Run Code Online (Sandbox Code Playgroud)

monads haskell

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

如何从多次运行 Haskell 基准测试中获得更有意义的统计数据

我正在使用该benchpress库运行一些相当简单的基准测试。我一直在使用bench :: Int -> IO a -> IO ()界面。但是,似乎如果我运行给定的函数n次数,第一个之后的所有运行都非常快。

作为一个简单的例子,bench 1 (seq (sum [1..100000]) (return ()))可能需要 10 秒左右。但是,bench 5 (seq (sum [1..100000]) (return ()))会产生这样的报告:

Times (ms)
   min    mean    +/-sd  median    max 
  0.001   2.657   5.937   0.001  13.277

Percentiles (ms)
  50%  0.001
  66%  0.002
  75%  0.002
  80%  0.002
  90%  13.277
  95%  13.277
  98%  13.277
  99%  13.277
 100%  13.277
Run Code Online (Sandbox Code Playgroud)

由于平均值是 2.6,我可以推断出第一次运行需要 13 秒,其他 4 秒非常快。

为什么会发生这种情况?如何确保基准测试的所有运行都具有代表性?该库还具有更细粒度的界面:benchmark :: Int -> IO a -> …

benchmarking haskell

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

如何通过 monad 转换器参数化 monad?

我想编写一种可以通过其 monad 转换器参数化的类型。我尝试了几件事,最终得到了一些类似的东西:

newtype Foo t a = Foo { unFoo :: t (State St) a }
Run Code Online (Sandbox Code Playgroud)

然后,我想要一堆实例:

deriving instance (MonadTrans t, Monad (t (State St))) => Monad (Foo t)
Run Code Online (Sandbox Code Playgroud)

最后,我使用适当的 monad 转换器实例化类型。我的代码类型检查,但我收到所有派生实例的警告:“没有明确的实现>>=”。如果我尝试运行它,当它遇到类型类函数时会出现未定义的错误。

有没有办法自动派生我需要的所有实例?我试图派生出更多的类,而不仅仅是Monad.

我也对一种更符合人体工程学的方式来完成同样的事情感兴趣——我必须不​​断手动包装和解开Foo构造函数,特别是当我尝试对其lift进行计算时,因为我无法弄清楚如何实现一个MonadTrans实例为了它。

monads haskell monad-transformers

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

编写 haskell 类型 pointfree (或其他编写类型级函数的方法)?

是否有组合器可以以 pointfree 风格编写 Haskell 类型?

我有一个类似的类型同义词:

type FooT m a = StateT State (ReaderT (Params m) m)
Run Code Online (Sandbox Code Playgroud)

我希望能够以 pointfree 风格编写它的右侧,以便实例化一个需要参数为 monad 转换器的类型类。即,有一些类型类,例如:

class (MonadTrans t, Bar (t Monad)) => Baz t where -- where Bar is some other typeclass
 ...
Run Code Online (Sandbox Code Playgroud)

我想用我的变压器堆栈实例化它。但是,我需要向它提供某种类型的东西(* -> *) -> * -> *,这意味着我需要编写一个类型级函数,以便将我的StateT State (ReaderT ...)转换器作为参数传递给类型类。

我尝试使用类型系列,但似乎它们需要完全应用。

haskell ghc

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

标签 统计

haskell ×4

monads ×2

benchmarking ×1

ghc ×1

monad-transformers ×1