关于Haskell的精彩之处.函数的类型几乎决定了它的实现.对于这一个就是这种情况,但是......我的大脑并没有在这里包围嵌套函数:
mkDyn :: (Typeable a) => ((a -> IO()) -> IO ()) -> ((Dynamic -> IO()) -> IO ())
Run Code Online (Sandbox Code Playgroud)
唯一的问题是如何处理将要求的fromDynamic调用中的错误处理,但是......一旦我完成了其余的事情,我就可以处理它.我猜想在某个地方需要有类似的东西.但我似乎无法得到包装器lambda的东西.
case fromDynamic x of
Just x -> f x
Nothing -> undefined -- TODO
Run Code Online (Sandbox Code Playgroud)
nom*_*olo 10
我想你想要的toDyn不是fromDynamic.所以让我们慢慢来:
mkDyn :: Typeable a =>
((a -> IO ()) -> IO ())
-> (Dynamic -> IO ())
-> IO ()
mkDyn k f = ...
Run Code Online (Sandbox Code Playgroud)
我们的返回类型应该是IO (),我们可以通过调用k或获取f.呼叫f对我们没有多大帮助,因为我们会以某种方式实现a Dynamic,但我们不能(明智地)做到这一点k.所以我们想打电话k. k需要另一个函数作为参数,所以让我们这样开始:
mkDyn k f = k (\a -> ...)
Run Code Online (Sandbox Code Playgroud)
所以函数的论点是Typeable a => a -> IO ().我们没有该类型的功能,但我们有类型的功能Dynamic -> IO ().由于Typeable约束,我们可以toDyn用来转变a为Dynamic:
mkDyn k f = k (\a -> f (toDyn a))
Run Code Online (Sandbox Code Playgroud)
有更简单的实现(例如,return ()或k (\a -> return ()),但这似乎是有道理的.
我欺骗并使用了Djinn程序.
我首先概括了给出的类型:
f :: (a -> c)
-> ((a -> b) -> b)
-> ((c -> b) -> b)
Run Code Online (Sandbox Code Playgroud)
该(a -> c)代表的toDyn功能作用,并c代表Dynamic. b代表IO ().
Djinn的结果非常简单:
@djinn (a -> c) -> ((a -> b) -> b) -> ((c -> b) -> b)
f a b c = b (\ d -> c (a d))
Run Code Online (Sandbox Code Playgroud)
使之更具体的(通过更换(a -> c)与toDyn功能),我们得到:
mkDyn :: (Typeable a) => ((a -> IO()) -> IO ()) -> ((Dynamic -> IO()) -> IO ())
mkDyn b c = b (\ d -> c (toDyn d))
Run Code Online (Sandbox Code Playgroud)
这与nominolo的答案相符.