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.
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 liquid 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With