如何在Haskell中实现此功能

如何在Haskell中实现此功能,haskell,Haskell,哈斯克尔真是太棒了。函数的类型几乎决定了它的实现。这次也是这样,但是。。。我的大脑并没有围绕着嵌套的函数: mkDyn :: (Typeable a) => ((a -> IO()) -> IO ()) -> ((Dynamic -> IO()) -> IO ()) 唯一的问题是如何处理fromDynamic调用中需要的错误处理,但是。。。等我把剩下的都弄清楚了,我就可以应付了。我猜在某个地方一定会有类似的事情发生。但我似乎还没弄明白兰姆达的包装材料 cas

哈斯克尔真是太棒了。函数的类型几乎决定了它的实现。这次也是这样,但是。。。我的大脑并没有围绕着嵌套的函数:

mkDyn :: (Typeable a) => ((a -> IO()) -> IO ()) -> ((Dynamic -> IO()) -> IO ())
唯一的问题是如何处理fromDynamic调用中需要的错误处理,但是。。。等我把剩下的都弄清楚了,我就可以应付了。我猜在某个地方一定会有类似的事情发生。但我似乎还没弄明白兰姆达的包装材料

case fromDynamic x of
  Just x -> f x
  Nothing -> undefined -- TODO 

我想你想要的是toDyn,而不是Dynamic。让我们慢慢来:

mkDyn :: Typeable a =>
         ((a -> IO ()) -> IO ())
      -> (Dynamic -> IO ())
      -> IO ()
mkDyn k f = ...
我们的返回类型应该是
IO()
,我们可以通过调用
k
f
来获得它。调用
f
对我们帮助不大,因为我们会以某种方式实现
动态
,但我们不能从
k
中(明智地)实现这一点。所以我们要调用
k
k
需要另一个函数作为它的参数,所以让我们这样开始:

mkDyn k f = k (\a -> ...)
因此,函数的参数是
可键入的a=>a->IO()
。我们没有那种类型的函数,但是我们有一种类型为
Dynamic->IO()
的函数。由于
Typeable
约束,我们可以使用
toDyn
a
转换为
Dynamic
,并获得:

mkDyn k f = k (\a -> f (toDyn a))
有一些更简单的实现(例如,
return()
k(\a->return())
),但这一个似乎有意义。

我作弊并使用了

我首先概括了给定的类型:

f :: (a -> c)
  -> ((a -> b) -> b)
  -> ((c -> b) -> b)
(a->c)
表示函数,
c
表示
Dynamic
b
表示
IO()

Djinn的结果出人意料地简单:

@djinn (a -> c) -> ((a -> b) -> b) -> ((c -> b) -> b)
f a b c = b (\ d -> c (a d))
更具体地说(通过将
(a->c)
替换为
toDyn
函数),我们得到:


哪些匹配。

哇,我甚至不知道Haskell有动态类型支持,更不用说它了。每天学习新东西。@Joey IIRC甚至有一个库可以用简单的赋值运算符编写命令式代码,但我忘了在哪里了。我想Haskell星球上曾经提到过它。这证明nominolo是djinn吗?@rampion Two可以玩这个游戏!
mkDyn=(.toDyn))
。我倾向于选择定点版本。我只在真正只是简单管道的情况下使用无点样式。任何(甚至轻微的)更复杂,下次读代码时我会后悔的。@Daniel Wagner使用了两次函数合成部分?我想我的大脑有点爆炸了。我喜欢stackoverflow,尤其是Haskell的问题。太棒了,谢谢你!
mkDyn :: (Typeable a) => ((a -> IO()) -> IO ()) -> ((Dynamic -> IO()) -> IO ())
mkDyn b c = b (\ d -> c (toDyn d))