如果我为高阶函数指定(我认为)正确的类型,则OCaml编译器拒绝该函数的第二次使用.
代码
let foo ():string =
let f: ('a -> string) -> 'a -> string = fun g v -> g v
in let h = string_of_int
in let i = string_of_float
in let x = f h 23
in let y = f i 23.0
in x ^ y
Run Code Online (Sandbox Code Playgroud)
导致以下错误消息
File "test.ml", line 6, characters 14-15: Error: This expression has type float -> string but an expression was expected of type int -> string
所以第一次使用f
似乎修复了它的第一个参数的类型 …
我是反应性香蕉和FRP的新手,所以如果我遗漏了一些明显的东西,我会道歉.
对于我的项目(GDB/MI前端),我使用了响应式香蕉(版本0.6.0.0)用于GUI和前端逻辑模块.前者工作得很好,但对于后者我显然需要额外的组合器.
其中之一是zipE :: Event t a -> Event t b -> Event t (a, b)
.不幸的是,我能想到的只是NetworkDescription monad中的一个解决方案,它changes
在事件类型中使用并且不是通用的:
zipE :: Event t Int -> Event t String -> NetworkDescription t (Event t (Int, String))
zipE ea eb = changes $ (,) <$> stepper 0 ea <*> stepper "" eb
Run Code Online (Sandbox Code Playgroud)
当然,我对此并不满意.因此,我想问一下如何在不使用的情况下实现通用的zipE函数changes
(不鼓励用于非GUI目的).
其他尝试失败,例如
zipE :: Num a => Event t a -> Event t b -> Event t (a,b)
zipE ea eb = …
Run Code Online (Sandbox Code Playgroud) 我想在我的项目中使用FRP(即反应香蕉0.6.0.0)(GDB/MI前端).但我在宣布活动网络方面遇到了麻烦.
GUI中有命令,GDB有停止事件.两者都需要处理,处理它们取决于系统的状态.
我目前的方法看起来像这样(我认为这是显示问题所需的最低复杂度):
data Command = CommandA | CommandB
data Stopped = ReasonA | ReasonB
data State = State {stateExec :: Exec, stateFoo :: Int}
data StateExec = Running | Stopped
create_network :: NetworkDescription t (Command -> IO ())
create_network = do
(eCommand, fCommand) <- newEvent
(eStopped, fStopped) <- newEvent
(eStateUpdate, fStateUpdate) <- newEvent
gdb <- liftIO $ gdb_init fStopped
let
eState = accumE initialState eStateUpdate
bState = stepper initialState eState
reactimate $ (handleCommand gdb fStateUpdate …
Run Code Online (Sandbox Code Playgroud) 我是 Rust 的新手,刚刚阅读了 Rust 书中编程的第二版。我想知道下面的问题,但到目前为止找不到答案。
定义函数时,可以移动一些参数。mut
如果您打算在函数内改变它们,您也可以声明它们(没有引用)。
mut
然而,对于调用者来说,这似乎没有任何意义。他们刚刚转移了所有权,在那之后数据会发生什么不是他们关心的,是吗?
那么,说 amut
和移动的参数实际上不是函数 API 的一部分是否正确?相反,它将该函数的实现细节泄露给它的签名。
感谢您帮助我更好地理解这一点。
问候,亚历克斯