0

I am beginner in programming via Haskell language. I am interested at writing function in Haskell, which has side effects like this (for educational purposes, it can have another side effect):

-- function foo behaves like random numbers generator
foo :: Int
{- foo = some magic -}
-- It can print True or False
print $ show (foo /= foo)

As I understood, I have to implement some type instance of Monad with such behaviour (like this: IO Why are side-effects modeled as monads in Haskell?). But I really don't understand how to write simple example of function for this purpose.

Community
  • 1
  • 1
Alex Aparin
  • 4,393
  • 5
  • 25
  • 51

1 Answers1

1

If foo really behaves like some RNG, it must have some monadic type, or take as an additional input the state of the RNG.

Here's an example, using the system RNG (which lives in the IO monad):

import System.Random

foo :: IO Int
foo = randomRIO (1,5)  -- random number between 1 and 5

main :: IO ()
main = do
  x <- foo
  y <- foo
  print $ x /= y

In main, we simply call foo twice, binding its results to x,y, which have type Int. Then, we can compare them as usual.

Note that we can not use foo /= foo since foo :: IO Int, an action returning an Int, and we can't compare actions, only basic data like integers. This is why we first execute the actions, and then compare their results.

The main could be written in one line exploiting some more advanced combinators

  main = print =<< ((/=) <$> foo <*> foo)
  -- or
  main = print =<< liftA2 (/=) foo foo

but I would not focus on these at the beginning.


A more general example of a side-effecful computation:

foo :: IORef String -> IO Int
foo s = do
  x <- readIORef s              -- reading a "variable"
  print x                       -- output
  w <- getLine                  -- input
  writeIORef s ("qwerty" ++ x)  -- writing a variable
  length <$> readIORef s

main :: IO ()
main = do
  s <- newIORef "dummy"
  print =<< foo s
chi
  • 111,837
  • 3
  • 133
  • 218
  • I know about System.Random. I just want to see some implementation of such behavior (for educational purposes, it can have another side effect) – Alex Aparin Jul 01 '16 at 08:45
  • @АлександрЛысенко I added an example... I'm not sure I understand what you really want. – chi Jul 01 '16 at 08:51
  • I want to create own monad, which allows to create functions with side effects. – Alex Aparin Jul 01 '16 at 08:58
  • 2
    Look up `State` if you simply want to read/write variables. Or `ST`. If you want input/output, you need `IO` or `StateT IO`. `State` and `StateT` have their implementation available on hackage. `IO` can not be implemented except by using low-level "unsafe" primitives. – chi Jul 01 '16 at 09:04