我一直在比较拉动式FRP(即netwire)和推拉式FRP(即反应性 - 香蕉)在游戏的实施中.一个优于另一个有优势吗?我注意到的事情是:
IO漂浮,这总是更好.我还错过了什么?
编辑,以减少基于意见:主要目标是尽可能具有表达/简洁的东西,没有时间泄漏.
更新:我发现Netwire的一个大问题是,似乎没有一种方便的方法来获得多个帧速率,如"修复你的时间步"一文中所述.
更新2:我解决这个问题的方法是让我的游戏模拟线返回一个Float -> IO ()获取alpha值并使用该alpha插值的所有GL调用.理想情况下,我应该能够通过一个"绘制函数"传递给另一个线程MVar并在该线程中运行它.男人,哈斯克尔太棒了.
更新3:在提出这个问题后的六个月里,我开发了一个基于Netwire 的简单渲染引擎,以及"实体组件编程"的概念.在这个过程中,我实际上没有发现使用FRP非常有用.Wire在某些情况下,s 的表现力实际上已成为障碍.问题集中在对象的"身份"上.在定义Wire类型的值时,它没有标识,即它可以在整个网络中多次重复使用,并且每次表示不同的物理事物.当你想要做一些像碰撞检测这样的事情并且无法遍历场景图时,这是一个巨大的痛苦,因为它不能在不融合成单根不透明线的情况下存在.在"玩具"示例中不会出现此问题,因为很容易准确指定哪些对象与哪些其他对象以哪种方式交互.我相信这是任何一种FRP的问题.
如果一些Haskell向导在这方面证明我错了,那将是很棒的,但我真的没有看到它的方法.此外,如果解释不是很好,我很抱歉,但如果不自己尝试,这并不容易理解.
我开始使用Netwire第5版了.
编写我想要将输入转换为输出的所有电线都没有问题.
现在是编写IO包装器以配合我的实际输入的时候了,我有点困惑.
我是否应该为s参数创建自定义会话类型Wire s e m a b并将传感器值嵌入其中?
如果是这样,我有以下问题:
Monoid s背景class (Monoid s, Real t) => HasTime t s | s -> t?它是干什么用的?Map String Double使用我的传感器读数,但是我的monoid应该如何处理字典呢?它应该留下偏见吗?右侧偏置?以上都不是?如果没有,我该怎么办?我想最终Wire s InhibitionReason Identity () Double得到一些形式的电线s,代表我的输入.
我的理解是,我不想或不需要为此目的使用monadic m参数Wire,允许电线本身是纯净的,并将IO限制在逐步通过顶层电线的代码中.这是不正确的?
在之前的SO问题中(是否可能?:行为t [行为ta] - >行为t [a])我们正在分析a Behavior join(使用reactive-banana术语)的存在.
Behavior t (Behavior t a) -> Behavior t a
Run Code Online (Sandbox Code Playgroud)
在语义模型中实现如下
type Behavior t a = t -> a
behaviorNow :: Behavior t (Behavior t a) -> Behavior t a
behaviorNow f t = f t t
Run Code Online (Sandbox Code Playgroud)
虽然实施这一直接将是不幸的,因为我们可以生产Behavior Monad使用const及behaviorNow,是否以及如何不behaviorNow违反FRP的语义?
我很乐意使用任何其他FRP系统的术语来听取答案,如果有意义的话,还要进行比较.
我正在尝试进入Netwire,我已经挖掘了文档,介绍,教程等等,但几乎所有的教程和现有代码都已经过时了Netwire 5并使用了Netwire 4中不再与之相关的功能我们.该自述是一种有益的,但不是万能的编译和它仍然勉强提供了上手的足够信息.
我要求解释或一个例子只是为了让游戏循环运行并能够响应事件,所以我寻求信息,所以我最终会知道:
main.还有其他相关的东西.
我认为从那里我可以得到一些运行的东西,所以我可以通过实验来学习其余的东西(因为第五版中的文档和教程的状态非常不存在,我希望很快会出现一些).
谢谢!
haskell functional-programming frp reactive-programming netwire
我仍然试图弄清楚箭头表示法和Haskell中定义的箭头类型类的语义之间的相似之处.特别是,这个问题似乎有一个用箭头符号写的小计数器的非常规范的例子:
counter :: ArrowCircuit a => a Bool Int
counter = proc reset -> do
rec output <- returnA -< if reset then 0 else next
next <- delay 0 -< output+1
returnA -< output
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我如何在没有箭头符号的情况下将其转换回Haskell2010吗?
为了试用Netwire,我正在使用该库实现Pong.在代码中我有一个球线和一个计算机桨线,由于它们相互依赖某些值,我一直遇到无限循环的问题.一些伪代码解释:
ball :: Wire () IO GameInput Ball
ball = (... define ball ...) . pcPaddle
pcPaddle :: Wire () IO GameInput Paddle
pcPaddle = (... define pcPaddle ...) . ball
Run Code Online (Sandbox Code Playgroud)
要注意的是他们互相接受投入.我试图通过执行以下操作来缓解此问题:
ball :: Wire () IO GameInput Ball
ball = ( ... ) . delay ( ... base paddle init ...) . pcPaddle
Run Code Online (Sandbox Code Playgroud)
以及delay在这两条线中使用函数的其他变体,但我得到的<<loop>>运行时错误无论如何.
如何初始化其中一根电线以使该系统可以工作?
我刚刚开始使用netwire,我遇到了很多基础问题.
以下代码对我来说很好:
main :: IO ()
main = testWire clockSession_ (for 3 . yeah)
yeah :: Monad m => Wire s () m a String
yeah = pure "yes"
Run Code Online (Sandbox Code Playgroud)
但这不是:
main :: IO ()
main = testWire clockSession_ forYeah
forYeah :: (Show b, Show e) => Wire s e Identity a b
forYeah = for 3 . yeah
Run Code Online (Sandbox Code Playgroud)
失败并出错:
Could not deduce (b ~ [Char])
from the context (Show b, Show e)
bound by the type signature for
forYeah :: …Run Code Online (Sandbox Code Playgroud) 我正在努力了解FRP和Netwire.我最好的实用知识来源是这篇文章,但它有点过时,因为它是用Netwire 4编写的,我使用的是5.0版.我希望玩家控制正方形,从屏幕边缘反弹.
根据这篇文章,我有这个:
acceleration :: (Monad m, Monoid e) => Wire s e m (Set SDL.Keysym) Double
acceleration = pure (-80) . when (keyDown SDL.SDLK_LEFT)
<|> pure 80 . when (keyDown SDL.SDLK_RIGHT)
<|> pure 0
velocity :: (Monad m, HasTime t s, Monoid e) => Wire s e m (Double, Bool) Double
velocity = integralWith limit 0
where limit collision v = let newV = if collision then -v else v in clampMax maxV newV
challenge2 :: (MonadFix …Run Code Online (Sandbox Code Playgroud) 我正在使用Netwire编写一个由来自网络的事件驱动的程序.我想这里有三个问题:
是什么让人Control.Wire.Unsafe.Event不安全?就像标题所说,我需要保持哪些不变量才能安全使用它?
我觉得我需要这样的东西:mapMaybeE :: Monad m => (a -> Maybe b) -> Wire s e m (Event a) (Event b).上下文是我有来自网络的消息,我想只响应其中一些消息.这就是我写的:
mapMaybeE :: Monad m => (a -> Maybe b) -> Wire s e m (Event a) (Event b)
mapMaybeE f = arr go . arr (fmap f)
where go WU.NoEvent = WU.NoEvent
go (WU.Event Nothing) = WU.NoEvent
go (WU.Event (Just a)) = WU.Event a
Run Code Online (Sandbox Code Playgroud)
这是"合法的"吗?或者如果没有事件,我是否应该禁止?
Netwire对这类问题有意义吗?我见过的所有例子都是不断循环的游戏.在这里,我只想在有事情要做的时候踩电线.大多数情况下,这将是网络事件,但我可能也想在计时器上做事情.例如,一个事件进入,然后五秒钟后程序执行某些操作.它不应该连续循环,直到会话中的时间比事件进入的时间大5秒.