Haskell newbie here.
I have a higher order function myTransform at hand, which takes a function fn :: String -> String and do some fancy things.
Let's assume the implementation is
myTransform :: Int -> (String -> String) -> String -> [String]
myTransform n f = take n . iterate f
now I want to transform an external program, which is, if I understand right, an IO action. Preferably, the signature should be String -> IO String:
import System.Process
externProg :: String -> IO String
externProg s = readProcess "echo" ["-n", s, "+ 1"] ""
the question is, is there any way I can fit this String -> IO String function into that String -> String argument slot, without changing, or even knowing, how myTransform implements?
No, you can not. You will have to make a monadic version of myTransform. It is custom to append a capital M. I.e. map becomes mapM. fold becomse foldM ... Unfortunately there is no iterateM. I would therefore skip
iterateMand implement it directly.You might notice that the results of the first function are ordered the other way around. This is in order to avoid the function being quadratic.
You can try yourself what will happen if you implement
iterateM. It will just loop eternally. This is because Haskell can never know if you will actually get a list back or if there will be an IOError somewhere down the road. Similarly if you take the Maybe monad, Haskell will never know if you actually get aJust listback or if down the road somewhere there is aNothing.