Jump to content

First class environments: Difference between revisions

→‎{{header|Haskell}}: Added Haskell solution
m (fixed typos)
(→‎{{header|Haskell}}: Added Haskell solution)
Line 482:
Counts:
0 1 7 2 5 8 16 3 19 6 14 9 </pre>
 
=={{header|Haskell}}==
 
First let's implement the algorithm of calculating Hailstone series:
<lang haskell>hailstone n
| n == 1 = 1
| even n = n `div` 2
| odd n = 3*n + 1</lang>
 
and a data structure representing the environment
 
<lang haskell>data Environment = Environment { count :: Int, value :: Int }
deriving Eq</lang>
 
In Haskell operations with first class environments could be implemented using several approaches:
 
1. Using any data structure <code>S</code> which is passed by a chain of functions, having type <code>S -> S</code>.
 
2. Using the <code>Reader</code> monad, which emulates access to imutable environment.
 
3. Using the <code>State</code> monad, which emulates access to an environment, that coud be changed.
 
For given task approaches 1 and 3 are suitable.
 
Let's define a collection of environments:
 
<lang haskell>environments = [ Environment 0 n | n <- [1..12] ]</lang>
 
and a <code>process</code>, which changes an environment according to a task.
 
Approach 1.
 
<lang haskell>process (Environment c 1) = Environment c 1
process (Environment c n) = Environment (c+1) (hailstone n)</lang>
 
Approach 3. (needs <code>import Control.Monad.State</code>)
 
<lang haskell>process = execState $ do
n <- gets value
c <- gets count
when (n > 1) $ modify $ \env -> env { count = c + 1 }
modify $ \env -> env { value = hailstone n }</lang>
 
Repetitive batch processing of a collection we implement as following:
 
<lang haskell>fixedPoint f x
| fx == x = [x]
| otherwise = x : fixedPoint f fx
where fx = f x
 
prettyPrint field = putStrLn . foldMap (format.field)
where format n = (if n < 10 then " " else "") ++ show n ++ " "
 
main = do
let result = fixedPoint (map process) environments
mapM_ (prettyPrint value) result
putStrLn (replicate 36 '-')
prettyPrint count (last result)</lang>
 
{{Out}}
<pre>1 2 3 4 5 6 7 8 9 10 11 12
1 1 10 2 16 3 22 4 28 5 34 6
1 1 5 1 8 10 11 2 14 16 17 3
1 1 16 1 4 5 34 1 7 8 52 10
1 1 8 1 2 16 17 1 22 4 26 5
1 1 4 1 1 8 52 1 11 2 13 16
1 1 2 1 1 4 26 1 34 1 40 8
1 1 1 1 1 2 13 1 17 1 20 4
1 1 1 1 1 1 40 1 52 1 10 2
1 1 1 1 1 1 20 1 26 1 5 1
1 1 1 1 1 1 10 1 13 1 16 1
1 1 1 1 1 1 5 1 40 1 8 1
1 1 1 1 1 1 16 1 20 1 4 1
1 1 1 1 1 1 8 1 10 1 2 1
1 1 1 1 1 1 4 1 5 1 1 1
1 1 1 1 1 1 2 1 16 1 1 1
1 1 1 1 1 1 1 1 8 1 1 1
1 1 1 1 1 1 1 1 4 1 1 1
1 1 1 1 1 1 1 1 2 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1
-----------------------------------
0 1 7 2 5 8 16 3 19 6 14 9 </pre>
 
Or in "transposed" way
 
<lang haskell>main = do
let result = map (fixedPoint process) environments
mapM_ (prettyPrint value) result
putStrLn (replicate 36 '-')
putStrLn "Counts: "
prettyPrint (count . last) result</lang>
 
{{Out}}
<pre> 1
2 1
3 10 5 16 8 4 2 1
4 2 1
5 16 8 4 2 1
6 3 10 5 16 8 4 2 1
7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
8 4 2 1
9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
10 5 16 8 4 2 1
11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
12 6 3 10 5 16 8 4 2 1
------------------------------------
Counts:
0 1 7 2 5 8 16 3 19 6 14 9 </pre>
 
=={{header|J}}==
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.