Wonderful thing about Haskell. The type of a function almost dictates its implementation. That's the case for this one, but... my brain just isn't wrapping around the nested function thing here:
mkDyn :: (Typeable a) => ((a -> IO()) -> IO ()) -> ((Dynamic -> IO()) -> IO ())
The only question is how to handle error handling in the fromDynamic call that will be required, but... I can deal with that once I have the rest figured out. I'm guessing there will need to be something like the following somewhere. But I can't seem to get the wrapper lambda stuff figured out.
case fromDynamic x of
Just x -> f x
Nothing -> undefined -- TODO
I think you want toDyn
, not fromDynamic
. So let's do this slowly:
mkDyn :: Typeable a =>
((a -> IO ()) -> IO ())
-> (Dynamic -> IO ())
-> IO ()
mkDyn k f = ...
Our return type should be IO ()
and we can obtain that either by calling k
or f
. Calling f
doesn't help us much, because we would somehow materialise a Dynamic
, but we cannot do that (sensibly) from k
. So we want to call k
. k
needs another function as its argument, so lets start like this:
mkDyn k f = k (\a -> ...)
So the function's argument is Typeable a => a -> IO ()
. We don't have a function of that type, but we have a function of type Dynamic -> IO ()
. Because of the Typeable
constraint we can use toDyn
to turn our a
into Dynamic
and get:
mkDyn k f = k (\a -> f (toDyn a))
There are simpler implementations (eg, return ()
or k (\\a -> return ())
, but this one appears to make sense.
I cheated and used the Djinn program .
I first generalized the type given:
f :: (a -> c)
-> ((a -> b) -> b)
-> ((c -> b) -> b)
The (a -> c)
represents the toDyn
function function, and c
represents Dynamic
. b
represents IO ()
.
Djinn's result was surprisingly simple:
@djinn (a -> c) -> ((a -> b) -> b) -> ((c -> b) -> b)
f a b c = b (\ d -> c (a d))
Making it more specific (by replacing the (a -> c)
with the toDyn
function), we get:
mkDyn :: (Typeable a) => ((a -> IO()) -> IO ()) -> ((Dynamic -> IO()) -> IO ())
mkDyn b c = b (\ d -> c (toDyn d))
which matches nominolo's answer .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.