Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transformation of (a -> IO b) to IO (a -> b)

I have several data types in an IO context like:

a :: IO String
b :: IO FilePath
c :: String -> IO String

I want to put them all together in one data object like:

data Configdata = Configdata String FilePath (String -> String)

So I don't have to get each value for its own out of the IO context, but just out of IO Configdata.

The critical point where I don't have a solution is how I can transform String -> IO String to IO (String -> String). Hoogle doesn't give me any functions which are capable of doing this.

I am not sure if it's maybe even not possible, since the input of the function is possibly infinite.

Does someone have a solution or an explanation why it's not possible? I know that using a list instead of a function is an option, but I would prefer using a function if possible.

like image 542
F. Böller Avatar asked Dec 25 '22 02:12

F. Böller


1 Answers

Indeed this is not possible. Consider the function:

import Acme.Missiles

boo :: String -> IO String
boo "cute" = return "Who's a nice kitty?"
boo "evil" = launchMissiles >> return "HTML tags lea͠ki̧n͘g fr̶ǫm ̡yo​͟ur eye͢s̸ ̛l̕ik͏e liq​uid pain"

Now, if it were possible to transform this to IO (String -> String), it would have to execute all possible IO actions for any input before returning the pure String -> String function. IOW, even if you only planned to use the function for kitten-watching purposes, it would entail nuclear holocaust.

Nevertheless, it may well be possible to do this for your specific application. In particular, if you know the function will only ever be called for a predetermined set of strings, you can pre-query them from IO and store the results in a map, which can then be indexed purely.

import qualified Data.Map as Map

puh :: IO (String -> String)
puh = fmap ((Map.!) . Map.fromList) . forM ["cute"] $ \q -> do
       res <- boo q
       return (q, res)

Of course, this may not be feasible performance-wise.

like image 137
leftaroundabout Avatar answered Jan 01 '23 17:01

leftaroundabout