gpt4 book ai didi

haskell - 创建多态函数的事件流 - 可能吗?如果是,如何?

转载 作者:行者123 更新时间:2023-12-04 14:42:42 25 4
gpt4 key购买 nike

我目前正在使用 react 香蕉学习 FRP,并想创建一个随机函数流。我想出了这个:

-- | take number generator, and some pulse event stream, generate random function stream
mkRandom :: (Random a,RandomGen g) => g -> Event t b -> Event t ((a,a) -> a)
mkRandom rng es = (\f -> \r -> fst $ f r) <$> (accumE first $ next <$> es)
where first = flip randomR rng
next _ prev range = randomR range g
where (a,g) = prev range

它似乎有效,我可以这样使用它:
randFuncs = mkRandom rnd (pulse 1000 time)
some = ($ (0,10::Int)) <$> randFuncs

但是,当然,当我尝试共享该流以生成不同类型的数字时:
some2 = ($ (0,10::Double)) <$> randFuncs

类型检查器提示,我理解。然后我尝试将函数概括为以下内容:
mkRandom :: (RandomGen g) => g -> Event t b -> Event t (forall a. Random a => (a,a) -> a)

然后 GHC 提示非法多态签名以及我是否想启用 ImpredicativeTypes。我做了很长一段时间试图注释所有内容以使其工作,但 GHC 总是提示它无法匹配类型。

我的问题是 - 有可能做我想做的事吗?我真的需要 ImpredicativeTypes 还是我做错了?

我认为 RankNTypes 应该足够了,但我还没有使用此类扩展的经验。

提前致谢!

编辑:

作为记录,现在我基于有用响应的解决方案是:
newtype RandomSource = Rand { getRand :: forall a. (Random a) => (a,a) -> [a] }

-- | take number generator and some pulse event stream, generate randomness stream
mkRandom :: RandomGen g => g -> Event t a -> Behavior t RandomSource
mkRandom rng es = fst <$> (accumB (next id (id,rng)) $ next <$> es)
where next _ (_,rng) = (Rand $ flip randomRs g1, g2)
where (g1,g2) = split rng

-- | take a rand. source, a range and a pulse, return stream of infinite lists of random numbers
randStream :: Random a => Behavior t RandomSource -> (a,a) -> Event t b -> Event t [a]
randStream funcs range pulse = ($ range) . getRand <$> funcs <@ pulse

最佳答案

ImpredicativeTypes是一个非常脆弱的扩展,它并没有得到真正的支持或维护,因此在新的 GHC 版本中不断突破。

更好的工作选择是使用 RankNTypes连同 newtype包装:

newtype PolyRandFun = PR { getPR :: forall a. Random a => (a,a) -> a) }

这需要您显式地包装和解开 newtype 构造函数,但在其他方面可以很好地传递像这样的多态函数。

不幸的是,在这种情况下,我预见到另一个问题。不同 Random a实例使用不同数量的随机生成器,例如 Integer为构建 Integer 而生成的原始随机数的数量结果甚至取决于范围的大小。所以你不能得到下一个 g不知道实际调用函数时使用的类型和范围。

幸运的是, System.Random 中有一个函数。可以解决这个问题的 API: split为您提供了一个新的随机生成器,当您确实需要完全独立地生成多个随机值时,可以将其传递到子计算中。

关于haskell - 创建多态函数的事件流 - 可能吗?如果是,如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32994152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com