简体   繁体   中英

How to implement this function in Haskell

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM