How to implement this function in Haskell

Great thing about Haskell. The type of function almost dictates its implementation. This is the case for this, but ... my brain just doesn't wrap itself around a nested function:

mkDyn :: (Typeable a) => ((a -> IO()) -> IO ()) -> ((Dynamic -> IO()) -> IO ()) 

The only question is how to handle the error handling in the fromDynamic call, which is required, but ... I can handle this as soon as I succeed. I suppose there should be something like the following. But I can’t imagine how lambda material wraps.

 case fromDynamic x of Just x -> fx Nothing -> undefined -- TODO 
+8
haskell
source share
2 answers

I think you want toDyn , not fromDynamic . So do it slowly:

 mkDyn :: Typeable a => ((a -> IO ()) -> IO ()) -> (Dynamic -> IO ()) -> IO () mkDyn kf = ... 

Our return type must be IO () , and we can get this either by calling k or f . Calling f does not help us much, because we somehow implement Dynamic , but we cannot do this (reasonably) from k . Therefore, we want to call k . k needs another function as an argument, so let's start like this:

 mkDyn kf = k (\a -> ...) 

So, the argument of the function Typeable a => a -> IO () . We do not have a function of this type, but we have a function of type Dynamic -> IO () . Due to Typeable limitation Typeable we can use toDyn to turn our a into Dynamic and get:

 mkDyn kf = k (\a -> f (toDyn a)) 

There are simpler implementations (like return () or k (\a -> return ()) , but that seems to make sense.

+10
source share

I cheated and used the Djinn program .

At first I generalized the given type:

 f :: (a -> c) -> ((a -> b) -> b) -> ((c -> b) -> b) 

(a -> c) represents the toDyn function , and c represents Dynamic . b represents IO () .

Djinn's result was surprisingly simple:

 @djinn (a -> c) -> ((a -> b) -> b) -> ((c -> b) -> b) fabc = b (\ d -> c (ad)) 

Making it more specific (replacing (a -> c) with the toDyn function), we get:

 mkDyn :: (Typeable a) => ((a -> IO()) -> IO ()) -> ((Dynamic -> IO()) -> IO ()) mkDyn bc = b (\ d -> c (toDyn d)) 

which corresponds to nominolo answer .

+4
source share

All Articles