我一直想给FRP一点时间,昨天我终于咬了一口,然后开始使用Netwire 5开始(这本身就是一个相当随意的选择,但我必须从某个地方开始!).我已经设法达到了"有效的代码"这一点,但我注意到了一些模式,我不确定它们是如何使用库的一部分,或者它们是否是我的症状.在某处做错了什么.
我从这个教程开始,这足以让我很容易地启动和运行 - 我现在有一个由简单的"递增数字"线控制的旋转立方体:
spin :: (HasTime t s, Monad m) => Wire s e m a GL.GLfloat
spin = integral 0 . 5
Run Code Online (Sandbox Code Playgroud)
当按下"Esc"时,应用程序将退出,使用netwire-input-glfw中提供的电线:
shouldQuit :: (Monoid e, Functor m, Monad m) => Wire s e (GLFWInputT m) a a
shouldQuit = keyPressed GLFW.Key'Escape
Run Code Online (Sandbox Code Playgroud)
这些之间的一个重要区别是spin永远不会抑制 - 它应该总是返回一些价值 - 同时一直shouldQuit抑制; 直到按键实际被按下,在这种情况下我退出了应用程序.
让我感到不安的是我最终不得不使用这些电线的方式.现在,它看起来像这样:
(wt', spinWire') <- stepWire spinWire st $ Right undefined
((qt', quitWire'), inp'') <- runStateT (stepWire quitWire st $ Right …Run Code Online (Sandbox Code Playgroud) 给出以下代码:
import Data.Word
data T = T deriving (Eq, Show)
class C a where f :: a -> ()
instance C T where f _ = ()
instance C Word16 where f _ = ()
main = return $ f 0x16
Run Code Online (Sandbox Code Playgroud)
GHC抱怨它无法推断文字的类型0x16应该与错误:
No instance for (Num a0) arising from the literal ‘22’
The type variable ‘a0’ is ambiguous
Run Code Online (Sandbox Code Playgroud)
很容易理解为什么会这样--Haskell允许数字文字属于具有实例的任何类型Num,并且在这里我们不能消除文字0x16(或22)应该是什么类型的歧义.
它也很清楚,作为一个人类阅读我想要做的事情 - 只有一个类可用的实例C满足Num约束,所以显然我打算使用那个,所以0x16应该被视为一个Word16.
我知道有两种方法可以修复它:使用其类型注释文字:
main = return …Run Code Online (Sandbox Code Playgroud)