
Hi, I’ve been tryimg to write a function with signature asString :: IO String -> String Does someone please have the patience to explain to me what the compiler error messages really mean for these two attempts and exactly what I’m doing (!!!) If I *do not* give this function any type signature then it works i.e.. asString ioStr = do str <- ioStr return $ str and the compiler tells me its signature is asString :: forall (m :: * -> *) b. Monad m => m b -> m b which, at this stage of my Haskell progress, is just pure Voodoo. Why isn’t it’s signature asString :: IO String -> String ? Another naive attempt is asString ioStr = str where str <- ioStr and then compiler says parse error on input ‘<-’ Many Thanks Mike

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Here is return's type signature: return :: Monad m => a -> m a What you are doing with the do notation can also be expressed as ioStr
= (\str -> return str).
do notation and bind both require you to have a value that has the same monad as before. Steven Williams My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 FA On 10/06/15 12:35, Mike Houghton wrote:
Hi,
I’ve been tryimg to write a function with signature
asString :: IO String -> String
Does someone please have the patience to explain to me what the compiler error messages really mean for these two attempts and exactly what I’m doing (!!!) If I *do not* give this function any type signature then it works i.e..
asString ioStr = do str <- ioStr return $ str
and the compiler tells me its signature is
asString :: forall (m :: * -> *) b. Monad m => m b -> m b
which, at this stage of my Haskell progress, is just pure Voodoo. Why isn’t it’s signature asString :: IO String -> String ?
Another naive attempt is asString ioStr = str where str <- ioStr
and then compiler says parse error on input ‘<-’
Many Thanks
Mike
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBAgAGBQJVeGo5AAoJEMrKbHRmmlT6N8UP/i/tAhDtyHiG3sgH3e5xAqyt JAsyX2JaBQVjERRVaJQy1+Pg9hNdGBCrVljxY0BH5B8np956bnuIEyZKtSc2i2Jc HM0lBesyzCYqw29QxAyFFno07iXQllocZaHUIgC4AoNYO5zNGSPYcNaB4O5SYoKl 83Cjz97BHgAHkvHpsLDLOpizOkP+CsXwi8s/KRKoidLkbQpmv9SpqiFvmm9u+UK1 emZF/4veFE4Ay3AvIsxMpn7M5hVoKgat1xyGX02IrenvkOL69IIYc+4OvzK49Lxg e8jrAehJDMh+U7zN+qVCY1ZyJbJF+uGawFC+XoswOdAra+Q23te77RKkligkmN7s ACut72hwTejZN/sIaORqZXuy+HUY1LjlJnlz0RCdG1CLkr3EaKG5ZCX3E2N8RnxL 1CKtEdtFJGDeBcIBh5my/7IC22loTpVhBhPU2DPo+iOP2sRsUs0nllbqbjGfGpuE m37dR/tfq9FKwqYS5RUuAcZ8fWuPdojmO2WvI4thHBGJhsRK4gqhAI4MnKLHBEoL xfyHSaoFif/jC7peF/+ZPjKSsIpCJU+R/tDUBM9u22o3IVeTs1sWGZXM7J32tlGc K/MTF/F3phcxwSCqb99WBHhXOIkKSgp47gx1INgDZFug/CgjUI1Sl4jvZ5j/45D5 +RlHcYv+qp4J8nI59pFW =Vunc -----END PGP SIGNATURE-----

And just as a note, you can't really ever get the value inside the IO monad out. IO is not pure / non-deterministic, since it depends on something outside the program, and there's no way to "make it pure", as it were. You have to do all your operations on that String within the context of an IO -aldiyen
On Jun 10, 2015, at 12:47, Steven Williams
wrote: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Here is return's type signature:
return :: Monad m => a -> m a
What you are doing with the do notation can also be expressed as ioStr
= (\str -> return str).
do notation and bind both require you to have a value that has the same monad as before.
Steven Williams My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 FA
On 10/06/15 12:35, Mike Houghton wrote: Hi,
I’ve been tryimg to write a function with signature
asString :: IO String -> String
Does someone please have the patience to explain to me what the compiler error messages really mean for these two attempts and exactly what I’m doing (!!!) If I *do not* give this function any type signature then it works i.e..
asString ioStr = do str <- ioStr return $ str
and the compiler tells me its signature is
asString :: forall (m :: * -> *) b. Monad m => m b -> m b
which, at this stage of my Haskell progress, is just pure Voodoo. Why isn’t it’s signature asString :: IO String -> String ?
Another naive attempt is asString ioStr = str where str <- ioStr
and then compiler says parse error on input ‘<-’
Many Thanks
Mike
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners -----BEGIN PGP SIGNATURE----- Version: GnuPG v2
iQIcBAEBAgAGBQJVeGo5AAoJEMrKbHRmmlT6N8UP/i/tAhDtyHiG3sgH3e5xAqyt JAsyX2JaBQVjERRVaJQy1+Pg9hNdGBCrVljxY0BH5B8np956bnuIEyZKtSc2i2Jc HM0lBesyzCYqw29QxAyFFno07iXQllocZaHUIgC4AoNYO5zNGSPYcNaB4O5SYoKl 83Cjz97BHgAHkvHpsLDLOpizOkP+CsXwi8s/KRKoidLkbQpmv9SpqiFvmm9u+UK1 emZF/4veFE4Ay3AvIsxMpn7M5hVoKgat1xyGX02IrenvkOL69IIYc+4OvzK49Lxg e8jrAehJDMh+U7zN+qVCY1ZyJbJF+uGawFC+XoswOdAra+Q23te77RKkligkmN7s ACut72hwTejZN/sIaORqZXuy+HUY1LjlJnlz0RCdG1CLkr3EaKG5ZCX3E2N8RnxL 1CKtEdtFJGDeBcIBh5my/7IC22loTpVhBhPU2DPo+iOP2sRsUs0nllbqbjGfGpuE m37dR/tfq9FKwqYS5RUuAcZ8fWuPdojmO2WvI4thHBGJhsRK4gqhAI4MnKLHBEoL xfyHSaoFif/jC7peF/+ZPjKSsIpCJU+R/tDUBM9u22o3IVeTs1sWGZXM7J32tlGc K/MTF/F3phcxwSCqb99WBHhXOIkKSgp47gx1INgDZFug/CgjUI1Sl4jvZ5j/45D5 +RlHcYv+qp4J8nI59pFW =Vunc -----END PGP SIGNATURE----- _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Mike, if you are trying to run a "hello world" program in ghci, here
are 2 working functions.
-- #1 : all it does is prompts for input and sends the value back to IO
module Text where
ioStr :: IO()
ioStr = do
putStrLn "enter anything"
str <- getLine
putStrLn str
-- #2 this program prepends the string you pass to it as an arg with "Hello"
str2str:: String -> String
str2str s = "Hello " ++ s
-- how to run:
-- #1 : ioStr
-- #2 : str2str "some text"
hope this helps
On 10 June 2015 at 19:08, aldiyen
And just as a note, you can't really ever get the value inside the IO monad out. IO is not pure / non-deterministic, since it depends on something outside the program, and there's no way to "make it pure", as it were. You have to do all your operations on that String within the context of an IO
-aldiyen
On Jun 10, 2015, at 12:47, Steven Williams
wrote: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Here is return's type signature:
return :: Monad m => a -> m a
What you are doing with the do notation can also be expressed as ioStr
= (\str -> return str).
do notation and bind both require you to have a value that has the same monad as before.
Steven Williams My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 FA
On 10/06/15 12:35, Mike Houghton wrote: Hi,
I’ve been tryimg to write a function with signature
asString :: IO String -> String
Does someone please have the patience to explain to me what the compiler error messages really mean for these two attempts and exactly what I’m doing (!!!) If I *do not* give this function any type signature then it works i.e..
asString ioStr = do str <- ioStr return $ str
and the compiler tells me its signature is
asString :: forall (m :: * -> *) b. Monad m => m b -> m b
which, at this stage of my Haskell progress, is just pure Voodoo. Why isn’t it’s signature asString :: IO String -> String ?
Another naive attempt is asString ioStr = str where str <- ioStr
and then compiler says parse error on input ‘<-’
Many Thanks
Mike
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners -----BEGIN PGP SIGNATURE----- Version: GnuPG v2
iQIcBAEBAgAGBQJVeGo5AAoJEMrKbHRmmlT6N8UP/i/tAhDtyHiG3sgH3e5xAqyt JAsyX2JaBQVjERRVaJQy1+Pg9hNdGBCrVljxY0BH5B8np956bnuIEyZKtSc2i2Jc HM0lBesyzCYqw29QxAyFFno07iXQllocZaHUIgC4AoNYO5zNGSPYcNaB4O5SYoKl 83Cjz97BHgAHkvHpsLDLOpizOkP+CsXwi8s/KRKoidLkbQpmv9SpqiFvmm9u+UK1 emZF/4veFE4Ay3AvIsxMpn7M5hVoKgat1xyGX02IrenvkOL69IIYc+4OvzK49Lxg e8jrAehJDMh+U7zN+qVCY1ZyJbJF+uGawFC+XoswOdAra+Q23te77RKkligkmN7s ACut72hwTejZN/sIaORqZXuy+HUY1LjlJnlz0RCdG1CLkr3EaKG5ZCX3E2N8RnxL 1CKtEdtFJGDeBcIBh5my/7IC22loTpVhBhPU2DPo+iOP2sRsUs0nllbqbjGfGpuE m37dR/tfq9FKwqYS5RUuAcZ8fWuPdojmO2WvI4thHBGJhsRK4gqhAI4MnKLHBEoL xfyHSaoFif/jC7peF/+ZPjKSsIpCJU+R/tDUBM9u22o3IVeTs1sWGZXM7J32tlGc K/MTF/F3phcxwSCqb99WBHhXOIkKSgp47gx1INgDZFug/CgjUI1Sl4jvZ5j/45D5 +RlHcYv+qp4J8nI59pFW =Vunc -----END PGP SIGNATURE----- _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Thanks for all the replies! It’s become a little clearer. However… (again this is naive begginer stuff.. ) if the signature is asString :: IO String -> String why is this not a pure function? The IO string has already been supplied - maybe via keyboard input - and so for the same IO String the function will always return the same value. Surely this behaviour is different to a monadic function that reads the keyboard and its output (rather than the input) could be different. ie if I give asString an input of IO “myString” then it will always return “myString” every time I invoke it with IO “myString” Many thanks Mike
On 10 Jun 2015, at 18:20, Imants Cekusins
wrote: Mike, if you are trying to run a "hello world" program in ghci, here are 2 working functions.
-- #1 : all it does is prompts for input and sends the value back to IO
module Text where
ioStr :: IO() ioStr = do putStrLn "enter anything" str <- getLine putStrLn str
-- #2 this program prepends the string you pass to it as an arg with "Hello"
str2str:: String -> String str2str s = "Hello " ++ s
-- how to run: -- #1 : ioStr -- #2 : str2str "some text"
hope this helps
On 10 June 2015 at 19:08, aldiyen
wrote: And just as a note, you can't really ever get the value inside the IO monad out. IO is not pure / non-deterministic, since it depends on something outside the program, and there's no way to "make it pure", as it were. You have to do all your operations on that String within the context of an IO
-aldiyen
On Jun 10, 2015, at 12:47, Steven Williams
wrote: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Here is return's type signature:
return :: Monad m => a -> m a
What you are doing with the do notation can also be expressed as ioStr
= (\str -> return str).
do notation and bind both require you to have a value that has the same monad as before.
Steven Williams My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 FA
On 10/06/15 12:35, Mike Houghton wrote: Hi,
I’ve been tryimg to write a function with signature
asString :: IO String -> String
Does someone please have the patience to explain to me what the compiler error messages really mean for these two attempts and exactly what I’m doing (!!!) If I *do not* give this function any type signature then it works i.e..
asString ioStr = do str <- ioStr return $ str
and the compiler tells me its signature is
asString :: forall (m :: * -> *) b. Monad m => m b -> m b
which, at this stage of my Haskell progress, is just pure Voodoo. Why isn’t it’s signature asString :: IO String -> String ?
Another naive attempt is asString ioStr = str where str <- ioStr
and then compiler says parse error on input ‘<-’
Many Thanks
Mike
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners -----BEGIN PGP SIGNATURE----- Version: GnuPG v2
iQIcBAEBAgAGBQJVeGo5AAoJEMrKbHRmmlT6N8UP/i/tAhDtyHiG3sgH3e5xAqyt JAsyX2JaBQVjERRVaJQy1+Pg9hNdGBCrVljxY0BH5B8np956bnuIEyZKtSc2i2Jc HM0lBesyzCYqw29QxAyFFno07iXQllocZaHUIgC4AoNYO5zNGSPYcNaB4O5SYoKl 83Cjz97BHgAHkvHpsLDLOpizOkP+CsXwi8s/KRKoidLkbQpmv9SpqiFvmm9u+UK1 emZF/4veFE4Ay3AvIsxMpn7M5hVoKgat1xyGX02IrenvkOL69IIYc+4OvzK49Lxg e8jrAehJDMh+U7zN+qVCY1ZyJbJF+uGawFC+XoswOdAra+Q23te77RKkligkmN7s ACut72hwTejZN/sIaORqZXuy+HUY1LjlJnlz0RCdG1CLkr3EaKG5ZCX3E2N8RnxL 1CKtEdtFJGDeBcIBh5my/7IC22loTpVhBhPU2DPo+iOP2sRsUs0nllbqbjGfGpuE m37dR/tfq9FKwqYS5RUuAcZ8fWuPdojmO2WvI4thHBGJhsRK4gqhAI4MnKLHBEoL xfyHSaoFif/jC7peF/+ZPjKSsIpCJU+R/tDUBM9u22o3IVeTs1sWGZXM7J32tlGc K/MTF/F3phcxwSCqb99WBHhXOIkKSgp47gx1INgDZFug/CgjUI1Sl4jvZ5j/45D5 +RlHcYv+qp4J8nI59pFW =Vunc -----END PGP SIGNATURE----- _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Hello, The key word here is "if I give asSting an input of IO "myString". Any function that returns and IO "myString" (this is really a misnomer, an (IO String) is a black box that stores the string obtained from an external source, but in an implementation-dependent, not-visible-to-an-user way) can do an arbitrary interaction with the real world to obtain the value. It can look at the keyborad input, read a file, connect to some networked resource, etc. That's why, this is not a pure function because every time you call it, it may return a different string. Or simply put, there's no legal way to write a function with that signature (okay, you can make it happen by using the unsafePerformIO function, but beware, it's called "unsafe" for a reason. It can cause a whole lot of seemingly "magic", unexpected behavior. In general, don't use it unless you really know it won't bite you) I don't know how to explain it more thoroughly. If you want to get deeper into Haskell, it could be said that ANY Haskell function or value is "pure" - for example an (IO String) value is always the same, well, (IO String) value, but the String "inside" may differ (just like a (Maybe String) or [String] is a wholly different beast than a mere String) If you want to connect pure functions to impure function do it the other way around - promote pure functions to IO (or any other monad). For example, you can use any pure function when using do notation easily. You can also compose any function of type (a -> b) with return to create a function (a -> m b). IO, being a monad, also implements many type classes from here: https://wiki.haskell.org/Typeclassopedia so you can turn a (a -> b) function into a (IO a -> IO b) function with just a fmap or <$>, for example. Best regards, Marcin Mrotek

On Wed, Jun 10, 2015 at 11:15 AM Marcin Mrotek
That's why, this is not a pure function because every time you call it, it may return a different string.
This is a common source of confusion. A value of type IO a for some a is not an impure function because it is not a function. Its *evaluation* is completely pure and referentially transparent: every time you evaluate `getLine`, you get the same IO String value. The only observable difference is under execution, but *we don't expect execution to be pure*: we only expect evaluation to be pure.

This is a common source of confusion. A value of type IO a for some a is not an impure function because it is not a function. Its evaluation is completely pure and referentially transparent: every time you evaluate `getLine`, you get the same IO String value. The only observable difference is under execution, but we don't expect execution to be pure: we only expect evaluation to be pure.
Yeah, this is what I was trying to say in the latter part of my post, but I guess I ended up confusing the matter more :( Best regards, Marcin Mrotek

impossible: asString :: IO String -> String here is an article which in addition to this thread clarified it for me: https://wiki.haskell.org/All_About_Monads search for: 4.3 No way out The IO monad is a familiar example of a one-way monad in Haskell. Because you can't escape from the IO monad, it is impossible to write a function that does a computation in the IO monad but whose result type does not include the IO type constructor. This means that any function whose result type does not contain the IO type constructor is guaranteed not to use the IO monad. ... There is no way to get rid of the IO type constructor in the signature of any function that uses it, so the IO type constructor acts as a kind of tag that identifies all functions that do I/O. Furthermore, such functions are only useful within the IO monad. So a one-way monad effectively creates an isolated computational domain in which the rules of a pure functional language can be relaxed. Functional computations can move into the domain, but dangerous side-effects and non-referentially-transparent functions cannot escape from it.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Assuming asString :: IO String -> String we have getLine :: IO String asString getLine :: String Yet asString getLine could be "Hello" the first time you use it, then "Hi" the second time you use it. Same argument, different result, so this is not a pure function. - -- Yannis On 10/06/2015 19:50, Mike Houghton wrote:
Thanks for all the replies! It’s become a little clearer. However… (again this is naive begginer stuff.. ) if the signature is
asString :: IO String -> String
why is this not a pure function? The IO string has already been supplied - maybe via keyboard input - and so for the same IO String the function will always return the same value. Surely this behaviour is different to a monadic function that reads the keyboard and its output (rather than the input) could be different. ie if I give asString an input of IO “myString” then it will always return “myString” every time I invoke it with IO “myString”
Many thanks
Mike
On 10 Jun 2015, at 18:20, Imants Cekusins
wrote: Mike, if you are trying to run a "hello world" program in ghci, here are 2 working functions.
-- #1 : all it does is prompts for input and sends the value back to IO
module Text where
ioStr :: IO() ioStr = do putStrLn "enter anything" str <- getLine putStrLn str
-- #2 this program prepends the string you pass to it as an arg with "Hello"
str2str:: String -> String str2str s = "Hello " ++ s
-- how to run: -- #1 : ioStr -- #2 : str2str "some text"
hope this helps
On 10 June 2015 at 19:08, aldiyen
wrote: And just as a note, you can't really ever get the value inside the IO monad out. IO is not pure / non-deterministic, since it depends on something outside the program, and there's no way to "make it pure", as it were. You have to do all your operations on that String within the context of an IO
-aldiyen
On Jun 10, 2015, at 12:47, Steven Williams
wrote: Here is return's type signature:
return :: Monad m => a -> m a
What you are doing with the do notation can also be expressed as ioStr
> = (\str -> return str).
do notation and bind both require you to have a value that has the same monad as before.
Steven Williams My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 FA
On 10/06/15 12:35, Mike Houghton wrote: Hi,
I’ve been tryimg to write a function with signature
asString :: IO String -> String
Does someone please have the patience to explain to me what the compiler error messages really mean for these two attempts and exactly what I’m doing (!!!) If I *do not* give this function any type signature then it works i.e..
asString ioStr = do str <- ioStr return $ str
and the compiler tells me its signature is
asString :: forall (m :: * -> *) b. Monad m => m b -> m b
which, at this stage of my Haskell progress, is just pure Voodoo. Why isn’t it’s signature asString :: IO String -> String ?
Another naive attempt is asString ioStr = str where str <- ioStr
and then compiler says parse error on input ‘<-’
Many Thanks
Mike
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
- -- Yannis JUGLARET

To be complete, my message actually assumes a function of that type *with the behavior you want*, which would be that of unsafePerformIO. Of course a trivial *pure* function with that type is for instance: asString _ = "Hi" But it does not have the behavior you want, it just ignores its argument. -- Yannis On 10/06/2015 20:22, Yannis Juglaret wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
Assuming
asString :: IO String -> String
we have
getLine :: IO String
asString getLine :: String
Yet
asString getLine
could be "Hello" the first time you use it, then "Hi" the second time you use it. Same argument, different result, so this is not a pure function.
- -- Yannis
On 10/06/2015 19:50, Mike Houghton wrote:
Thanks for all the replies! It’s become a little clearer. However… (again this is naive begginer stuff.. ) if the signature is
asString :: IO String -> String
why is this not a pure function? The IO string has already been supplied - maybe via keyboard input - and so for the same IO String the function will always return the same value. Surely this behaviour is different to a monadic function that reads the keyboard and its output (rather than the input) could be different. ie if I give asString an input of IO “myString” then it will always return “myString” every time I invoke it with IO “myString”
Many thanks
Mike
On 10 Jun 2015, at 18:20, Imants Cekusins
wrote: Mike, if you are trying to run a "hello world" program in ghci, here are 2 working functions.
-- #1 : all it does is prompts for input and sends the value back to IO
module Text where
ioStr :: IO() ioStr = do putStrLn "enter anything" str <- getLine putStrLn str
-- #2 this program prepends the string you pass to it as an arg with "Hello"
str2str:: String -> String str2str s = "Hello " ++ s
-- how to run: -- #1 : ioStr -- #2 : str2str "some text"
hope this helps
On 10 June 2015 at 19:08, aldiyen
wrote: And just as a note, you can't really ever get the value inside the IO monad out. IO is not pure / non-deterministic, since it depends on something outside the program, and there's no way to "make it pure", as it were. You have to do all your operations on that String within the context of an IO
-aldiyen
On Jun 10, 2015, at 12:47, Steven Williams
wrote: Here is return's type signature:
return :: Monad m => a -> m a
What you are doing with the do notation can also be expressed as ioStr
>> = (\str -> return str).
do notation and bind both require you to have a value that has the same monad as before.
Steven Williams My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 FA
> On 10/06/15 12:35, Mike Houghton wrote: Hi, > > I’ve been tryimg to write a function with signature > > asString :: IO String -> String > > > Does someone please have the patience to explain to me > what the compiler error messages really mean for these > two attempts and exactly what I’m doing (!!!) If I *do > not* give this function any type signature then it works > i.e.. > > asString ioStr = do str <- ioStr return $ str > > and the compiler tells me its signature is > > asString :: forall (m :: * -> *) b. Monad m => m b -> m > b > > which, at this stage of my Haskell progress, is just pure > Voodoo. Why isn’t it’s signature asString :: IO String > -> String ? > > > Another naive attempt is asString ioStr = str where str > <- ioStr > > and then compiler says parse error on input ‘<-’ > > > Many Thanks > > Mike > > _______________________________________________ Beginners > mailing list Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
- -- Yannis JUGLARET
-- Yannis JUGLARET

On Wed, Jun 10, 2015 at 10:50 AM Mike Houghton
The IO string has already been supplied - maybe via keyboard input -
A value of type IO String has been provided, but a value of type IO String *is not a string.* In much the same way that `ls` is not a list of files, but rather a recipe for retrieving a list of files, a value of type IO String is a not a String but a recipe for performing IO that will retrieve a String once it is executed. It is important to remember is that *evaluating an IO action does not execute it*. Only the runtime system can do that, and the only IO action the runtime system executes is main (which can, of course, be composed of many other IO actions by using, e.g., the Monad interface). You can't write a function of type IO String -> String that "retrieves" the string because there is no string to retrieve. There is only a recipe that must be *executed* and that execution must stay within the IO context. (It is possible to write this function using unsafePerformIO precisely because unsafePerformIO instructs the runtime to ignore its usual safety mechanisms (that ensure that IO actions can be used with in a safe, pure, and referentially transparent way) and force the execution of the IO action as part of its evalulation and, as the name suggests, this is unsafe for a number of reasons and should only be used when the programmer is willing to take on the obligation to prove that they are using it in safe way.)

On Wed, Jun 10, 2015 at 12:35 PM, Mike Houghton wrote: asString ioStr = do
str <- ioStr
return $ str and the compiler tells me its signature is asString :: forall (m :: * -> *) b. Monad m => m b -> m b which, at this stage of my Haskell progress, is just pure Voodoo.
Why isn’t it’s signature asString :: IO String -> String ? Because the only thing it knows about ioStr is that it is a monadic action.
IO is not the only monad, nor even the only useful monad. And "do" syntax
including <- is not specific to IO.
That said, most of the type signature it showed you is only important if
you are doing advanced things like type level programming. The short
version of that type signature is
asString :: Monad m -> m b -> m b
asString ioStr = str where str <- ioStr and then compiler says
parse error on input ‘<-’ <- is part of "do" syntax, it cannot be used by itself like that.
Just to give you some idea of what's really going on, let me show you that
first one without the "do" syntax:
asString ioStr = ioStr >>= (\s -> return $ s)
(Let me additionally note that the "$" does nothing whatsoever in either
case, and can and should be left out. Moreover, (x >>= \y -> return y) is
just a long-winded way of writing (x).)
--
brandon s allbery kf8nh sine nomine associates
allbery.b@gmail.com ballbery@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

On Wed, Jun 10, 2015 at 1:06 PM, Brandon Allbery
asString :: Monad m -> m b -> m b
Typoed, sigh.... asString :: Monad m => m b -> m b The thing before the => is a "constraint", in this specifying that the type "m" must be a type for which an instance of the Monad typeclass has been defined. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
participants (8)
-
aldiyen
-
Brandon Allbery
-
Imants Cekusins
-
Marcin Mrotek
-
Mike Houghton
-
Rein Henrichs
-
Steven Williams
-
Yannis Juglaret