Pure Functional programming in OCaml ????

"Douglas Lewit [email protected] [ocaml_beginners]" <[email protected]> Sat, 20 May 2017 02:40:35 -0500
Newsgroups gmane.comp.lang.ocaml.beginners
Message-ID <CAM0XMJRnevbs5Ts=scYwsrHwVUfWo9xOP9S7rSmXAXQmgT=L8A@mail.gmail.com>
--001a11417d0ee85c94054fefc061
Content-Type: text/plain; charset="UTF-8"

*(* Here I am experimenting with OCaml's module system to see what I can do
with it! *)*


*module type PascalsSig = *

*(* pascals_Triangle and combination are the only "public methods"--using
JAVA language--in the    *

*   module, Pascal.  The other "methods" in the module are not available
outside of the module.  *

*   Again using JAVA language, we could say that those methods are "private
methods". *) *

*sig*

*    val pascals_Triangle : int -> int list list ;;*

*    val combination : int -> int -> int ;;*

*end ;;*


*module Pascal : PascalsSig = *

*struct*

*    let adjacent_sums list_ = let most = List.rev ( List.tl ( List.rev
list_ ) ) in *

*                              let rest = List.tl list_ in *

*                              let sum_pairs (t : int * int) : int = (fst
t) + (snd t) in *

*                              let adjacent_list = List.rev begin
List.fold_left2 (fun x y z -> (y, z) :: x) [] most rest end *

*                              in 1 :: begin List.map sum_pairs
adjacent_list end @ [1] ;;*


*    let rec pascals_triangle (triangle : int list list) (current_row : int
list) (initial : int) (nrows : int) = *

*            if nrows < 0 then raise ( Invalid_argument "Argument must be
non-negative!" )*

*            else if initial = nrows then [1] :: List.rev triangle *

*                 else pascals_triangle (current_row :: triangle)
(adjacent_sums current_row) (initial + 1) nrows ;;*


*    (* Here is an example of partial function application. *)*

*    let pascals_Triangle = pascals_triangle [] [1; 1] 0 ;;*


*    let combination n r = let triangle = pascals_Triangle n in*

*                          List.nth (List.nth triangle n) r ;;*


*end ;;*


*print_string "\nHow many rows of Pascal's Triangle do you want to compute?
" ;;*


*let nrows = read_int () ;;*


*let rec print_int_list ( ls : int list ) : unit = *

*                                           match ls with *

*                                           |[]                ->
print_endline "" ;*

*                                           |head :: []        ->
print_string (string_of_int head);*

*
print_int_list [];*

*                                           |head :: tail      ->
print_string (string_of_int head ^ ", "); *

*
print_int_list tail ;;*


*print_newline () ;;*


*List.map print_int_list (Pascal.pascals_Triangle (nrows - 1)) ;;*


*print_newline () ;;*



*let n = ref 0 ;;*


*let r = ref 0 ;;*


*print_string "Would you like to compute a specific Binomial Coefficient or
C(n, r) value?  Answer Y or N: " ;;*


*let user_input = read_line () ;;*


*if user_input = "Y"*

*then begin*

*     print_string "Enter some positive integer for n: " ;*

*     n := int_of_string (read_line ()) ;*

*     print_string "Enter some integer for r.\nr must be non-negative and
less than or equal to n: " ;*

*     r := int_of_string (read_line ()) ;*

*     print_endline ("The Binomial Coefficient or C(n, r) is equal to: " ^
(string_of_int (Pascal.combination n.contents r.contents))) ;*

*     print_newline ();*

*     end*

*else*

*     print_newline ();*


I like this a lot.  I was playing around with OCaml (something I don't
always have time for) and I really like how I got this done, and along the
way re-learned some stuff that I thought I had forgotten.  What's
interesting to me is that the end of the program is almost entirely
imperative, with all the user input and output.  "They" ( i.e. the
functional programming experts ) claim that Haskell is purely functional,
but if so then how does Haskell deal with stuff like user input, writing to
standard output, generating random integers, etc?  Yes, I'm sure someone is
going to tell me that Haskell uses "monads" to accomplish these miracles,
but please don't use that word unless you are prepared to explain to me
what a monad is!


I did some online reading, and apparently monads are found in other
languages too.  Scala has them, and I think OCaml has them as well, but
they are sort of "hidden under the hood" so the programmer in those
languages can work with monads without even really knowing what they are,
or at least without knowing their formal definition.  Judging from the
little I've read on the subject, I believe that "monads" are a way to
completely separate the part of the language that is functional from the
part of the language that produces side-effects.  I think in Haskell for
example an IO Integer is not the same as an Integer, but then.... how does
the programmer in Haskell cast one of those types to the other type?  If
you can't cast an Integer type to an IO Integer type, then what does the
Haskell programmer do if he or she wants to send the Integer value to
standard output or to some file in the current working directory?  Very
confusing!  OCaml is a little less intimidating to me because it's not
fully functional.... although here's my question. * IF I REALLY WANTED TO,
COULD I PROGRAM IN OCAML IN A PURELY FUNCTIONAL MANNER?*  Is that really
possible?  No reference variables.  No for or while loops.  No
side-effects?  The program above works great!  But what would it look like
if I changed it to something that was completely, 100% purely functional,
the OCaml equivalent to a Haskell program?


I appreciate the feedback!


Best,


Douglas Lewit

--001a11417d0ee85c94054fefc061
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable




<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/htm=
l4/strict.dtd">
<html>
<head>
</head>






=20
<body style=3D"background-color: #fff;">
<span style=3D"display:none">&nbsp;</span>

<!--~-|**|PrettyHtmlStartT|**|-~-->
<div id=3D"ygrp-mlmsg" style=3D"position:relative;">
  <div id=3D"ygrp-msg" style=3D"z-index: 1;">
<!--~-|**|PrettyHtmlEndT|**|-~-->

    <div id=3D"ygrp-text" >
=20=20=20=20=20=20
=20=20=20=20=20=20
      <p><div dir=3D"ltr">







<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">(=
* Here I am experimenting with OCaml&#39;s module system to see what I can =
do with it! *)</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">m=
odule type PascalsSig =3D=C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">(=
* pascals_Triangle and combination are the only &quot;public methods&quot;-=
-using JAVA language--in the =C2=A0 =C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 module, Pascal.=C2=A0 The other &quot;methods&quot; in the mod=
ule are not available outside of the module. =C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 Again using JAVA language, we could say that those methods are=
 &quot;private methods&quot;. *)=C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">s=
ig</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 val pascals_Triangle : int -&gt; int list list ;;</font></b><=
/span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 val combination : int -&gt; int -&gt; int ;;</font></b></span=
></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">e=
nd ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">m=
odule Pascal : PascalsSig =3D=C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">s=
truct</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 let adjacent_sums list_ =3D let most =3D List.rev ( List.tl (=
 List.rev list_ ) ) in=C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 let rest =3D List.tl list_ in=C2=A0</font><=
/b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 let sum_pairs (t : int * int) : int =3D (fs=
t t) + (snd t) in=C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 let adjacent_list =3D List.rev begin List.f=
old_left2 (fun x y z -&gt; (y, z) :: x) [] most rest end=C2=A0</font></b></=
span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 in 1 :: begin List.map sum_pairs adjacent_l=
ist end @ [1] ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 let rec pascals_triangle (triangle : int list list) (current_=
row : int list) (initial : int) (nrows : int) =3D=C2=A0</font></b></span></=
p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if nrows &lt; 0 then raise ( Inva=
lid_argument &quot;Argument must be non-negative!&quot; )</font></b></span>=
</p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else if initial =3D nrows then [1=
] :: List.rev triangle=C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else pascals_=
triangle (current_row :: triangle) (adjacent_sums current_row) (initial + 1=
) nrows ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 (* Here is an example of partial function application. *)</fo=
nt></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 let pascals_Triangle =3D pascals_triangle [] [1; 1] 0 ;;</fon=
t></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 let combination n r =3D let triangle =3D pascals_Triangle n i=
n</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 List.nth (List.nth triangle n) r ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">e=
nd ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">p=
rint_string &quot;\nHow many rows of Pascal&#39;s Triangle do you want to c=
ompute? &quot; ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">l=
et nrows =3D read_int () ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">l=
et rec print_int_list ( ls : int list ) : unit =3D=C2=A0</font></b></span><=
/p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 match ls with=C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 |[]=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -&gt;=C2=A0 =
print_endline &quot;&quot; ;</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 |head :: []=C2=A0 =C2=A0 =C2=A0 =C2=A0 -&gt;=C2=A0 print_string (string=
_of_int head);</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 print_int_list [];</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 |head :: tail=C2=A0 =C2=A0 =C2=A0 -&gt;=C2=A0 print_string (string_of_i=
nt head ^ &quot;, &quot;);=C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 print_int_list tail ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">p=
rint_newline () ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">L=
ist.map print_int_list (Pascal.pascals_Triangle (nrows - 1)) ;;</font></b><=
/span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">p=
rint_newline () ;;</font></b></span></p>
<p class=3D"gmail-p2"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">l=
et n =3D ref 0 ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">l=
et r =3D ref 0 ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">p=
rint_string &quot;Would you like to compute a specific Binomial Coefficient=
 or C(n, r) value?=C2=A0 Answer Y or N: &quot; ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">l=
et user_input =3D read_line () ;;</font></b></span></p>
<p class=3D"gmail-p2"><b><font color=3D"#0000ff"><span class=3D"gmail-s1"><=
/span><br></font></b></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">i=
f user_input =3D &quot;Y&quot;</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">t=
hen begin</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 print_string &quot;Enter some positive integer for n: &=
quot; ;</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 n :=3D int_of_string (read_line ()) ;</font></b></span>=
</p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 print_string &quot;Enter some integer for r.\nr must be=
 non-negative and less than or equal to n: &quot; ;</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 r :=3D int_of_string (read_line ()) ;</font></b></span>=
</p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 print_endline (&quot;The Binomial Coefficient or C(n, r=
) is equal to: &quot; ^ (string_of_int (Pascal.combination n.contents r.con=
tents))) ;</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 print_newline ();</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 end</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">e=
lse</font></b></span></p>
<p class=3D"gmail-p1"><span class=3D"gmail-s1"><b><font color=3D"#0000ff">=
=C2=A0=C2=A0 =C2=A0 print_newline ();</font></b></span></p><p class=3D"gmai=
l-p1"><span class=3D"gmail-s1"><br></span></p><p class=3D"gmail-p1"><span c=
lass=3D"gmail-s1"><font size=3D"4">I like this a lot.=C2=A0 I was playing a=
round with OCaml (something I don&#39;t always have time for) and I really =
like how I got this done, and along the way re-learned some stuff that I th=
ought I had forgotten.=C2=A0 What&#39;s interesting to me is that the end o=
f the program is almost entirely imperative, with all the user input and ou=
tput. =C2=A0&quot;They&quot; ( i.e. the functional programming experts ) cl=
aim that Haskell is purely functional, but if so then how does Haskell deal=
 with stuff like user input, writing to standard output, generating random =
integers, etc?=C2=A0 Yes, I&#39;m sure someone is going to tell me that Has=
kell uses &quot;monads&quot; to accomplish these miracles, but please don&#=
39;t use that word unless you are prepared to explain to me what a monad is=
! =C2=A0</font></span></p><p class=3D"gmail-p1"><span class=3D"gmail-s1"><f=
ont size=3D"4"><br></font></span></p><p class=3D"gmail-p1"><span class=3D"g=
mail-s1"><font size=3D"4">I did some online reading, and apparently monads =
are found in other languages too.=C2=A0 Scala has them, and I think OCaml h=
as them as well, but they are sort of &quot;hidden under the hood&quot; so =
the programmer in those languages can work with monads without even really =
knowing what they are, or at least without knowing their formal definition.=
=C2=A0 Judging from the little I&#39;ve read on the subject, I believe that=
 &quot;monads&quot; are a way to completely separate the part of the langua=
ge that is functional from the part of the language that produces side-effe=
cts.=C2=A0 I think in Haskell for example an IO Integer is not the same as =
an Integer, but then.... how does the programmer in Haskell cast one of tho=
se types to the other type?=C2=A0 If you can&#39;t cast an Integer type to =
an IO Integer type, then what does the Haskell programmer do if he or she w=
ants to send the Integer value to standard output or to some file in the cu=
rrent working directory?=C2=A0 Very confusing!=C2=A0 OCaml is a little less=
 intimidating to me because it&#39;s not fully functional.... although here=
&#39;s my question. <b><i>=C2=A0IF I REALLY WANTED TO, COULD I PROGRAM IN O=
CAML IN A PURELY FUNCTIONAL MANNER?</i></b> =C2=A0Is that really possible?=
=C2=A0 No reference variables.=C2=A0 No for or while loops.=C2=A0 No side-e=
ffects?=C2=A0 The program above works great!=C2=A0 But what would it look l=
ike if I changed it to something that was completely, 100% purely functiona=
l, the OCaml equivalent to a Haskell program?</font></span></p><p class=3D"=
gmail-p1"><span class=3D"gmail-s1"><font size=3D"4"><br></font></span></p><=
p class=3D"gmail-p1"><span class=3D"gmail-s1"><font size=3D"4">I appreciate=
 the feedback!</font></span></p><p class=3D"gmail-p1"><span class=3D"gmail-=
s1"><font size=3D"4"><br></font></span></p><p class=3D"gmail-p1"><span clas=
s=3D"gmail-s1"><font size=3D"4">Best,</font></span></p><p class=3D"gmail-p1=
"><span class=3D"gmail-s1"><font size=3D"4"><br></font></span></p><p class=
=3D"gmail-p1"><span class=3D"gmail-s1"><font size=3D"4">Douglas Lewit</font=
></span></p><p class=3D"gmail-p1"><span class=3D"gmail-s1"><font size=3D"4"=
><br></font></span></p></div>
</p>

    </div>
=20=20=20=20=20

    <!--~-|**|PrettyHtmlStart|**|-~-->
    <div style=3D"color: #fff; height: 0;">__._,_.___</div>

=20=20=20=20=20=20=20=20=20=20
=20=20
=20

=20=20=20=20
    <div style=3D"clear:both"> </div>

    <div id=3D"fromDMARC" style=3D"margin-top: 10px;">
        <hr style=3D"height:2px ; border-width:0; color:#E3E3E3; background=
-color:#E3E3E3;">
        Posted by: Douglas Lewit &lt;[email protected]&gt;        <hr style=
=3D"height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E3E3;">
     </div>
    <div style=3D"clear:both"> </div>

    <table cellspacing=3D4px style=3D"margin-top: 10px; margin-bottom: 10px=
; color: #2D50FD;">
      <tbody>
        <tr>
          <td style=3D"font-size: 12px; font-family: arial; font-weight: bo=
ld; padding: 7px 5px 5px;"  >
                          <a style=3D"text-decoration: none; color: #2D50FD=
" href=3D"https://groups.yahoo.com/neo/groups/ocaml_beginners/conversations=
/messages/14811;_ylc=3DX3oDMTJxdWtwcHQ5BF9TAzk3MzU5NzE0BGdycElkAzQ5OTkxOTQE=
Z3Jwc3BJZAMxNzA1MDA2NzY0BG1zZ0lkAzE0ODExBHNlYwNmdHIEc2xrA3JwbHkEc3RpbWUDMTQ=
5NTI2NjM2NQ--?act=3Dreply&messageNum=3D14811">Reply via web post</a>
                      </td>
          <td>&bull;</td>
          <td style=3D"font-size: 12px; font-family: arial; padding: 7px 5p=
x 5px;" >
            <a href=3D"mailto:[email protected]?subject=3DRe%3A%20Pure%20Fu=
nctional%20programming%20in%20OCaml%20%3F%3F%3F%3F" style=3D"text-decoratio=
n: none; color: #2D50FD;">
               Reply to sender            </a>
          </td>
          <td>&bull;</td>
          <td style=3D"font-size: 12px; font-family: arial; padding: 7px 5p=
x 5px;">
            <a href=3D"mailto:[email protected]?subject=3DRe%=
3A%20Pure%20Functional%20programming%20in%20OCaml%20%3F%3F%3F%3F" style=3D"=
text-decoration: none; color: #2D50FD">
              Reply to group            </a>
          </td>
          <td>&bull;</td>
          <td style=3D"font-size: 12px; font-family: arial; padding: 7px 5p=
x 5px;" >
            <a href=3D"https://groups.yahoo.com/neo/groups/ocaml_beginners/=
conversations/newtopic;_ylc=3DX3oDMTJlcjJ2cmFtBF9TAzk3MzU5NzE0BGdycElkAzQ5O=
TkxOTQEZ3Jwc3BJZAMxNzA1MDA2NzY0BHNlYwNmdHIEc2xrA250cGMEc3RpbWUDMTQ5NTI2NjM2=
NQ--" style=3D"text-decoration: none; color: #2D50FD">Start a New Topic</a>
          </td>
          <td>&bull;</td>
          <td style=3D"font-size: 12px; font-family: arial; padding: 7px 5p=
x 5px;color: #2D50FD;" >
                            <a href=3D"https://groups.yahoo.com/neo/groups/=
ocaml_beginners/conversations/topics/14811;_ylc=3DX3oDMTM2amg4MnFjBF9TAzk3M=
zU5NzE0BGdycElkAzQ5OTkxOTQEZ3Jwc3BJZAMxNzA1MDA2NzY0BG1zZ0lkAzE0ODExBHNlYwNm=
dHIEc2xrA3Z0cGMEc3RpbWUDMTQ5NTI2NjM2NQR0cGNJZAMxNDgxMQ--" style=3D"text-dec=
oration: none; color: #2D50FD;">Messages in this topic</a>
                (1)
                      </td>
        </tr>
      </tbody>
    </table>

=20=20=20=20=20=20=20=20
<div id=3D"megaphoneModule">
            <hr style=3D"height:2px ; border-width:0; color:#E3E3E3; backgr=
ound-color:#E3E3E3;">
        <div>
	     <div class=3D"stream" style=3D"margin-bottom:10px;">
        <div style=3D"background-color:white;">
            <div class=3D"sn-img" style=3D"display:inline;"><img name=3D"tn=
_file" style=3D"padding:0px 10px;vertical-align:top;margin-top:5px;" src=3D=
"https://s.yimg.com/ru/static/images/yg/img/megaphone/1464031581_phpFA8bON"=
 height=3D"82" width=3D"82"></div>
            <div class=3D"mod-txt" style=3D"display:inline-block;">
                <a rel=3D"nofollow" name=3D"sub_url" target=3D"_blank" href=
=3D"https://yho.com/1wwmgg" style=3D"color:#0000FF;display:block;margin-lef=
t:5px;text-decoration:none;"><span style=3D"font-size:15px;">Have you tried=
 the highest rated email app?</span></a>
                <div style=3D"max-width:530px;padding:2px 5px;">With 4.5 st=
ars in iTunes, the Yahoo Mail app is the highest rated email app on the mar=
ket. What are you waiting for? Now you can access all your inboxes (Gmail, =
Outlook, AOL and more) in one place. Never delete an email again with 1000G=
B of free cloud storage.</div>
            </div>
        </div>
    </div>        </div>=20=20
=20=20=20=20=20
    <hr style=3D"height:2px ; border-width:0; color:#E3E3E3; background-col=
or:#E3E3E3;">
</div>

<!------- Start Nav Bar ------>


    <div id=3D"ygrp-grfd" style=3D"font-family: Verdana; font-size: 12px; p=
adding: 15px 0;">
=20=20=20=20=20=20
<!-- |**|begin egp html banner|**| -->

      Archives up to December 31, 2011 are also downloadable at <a href=3D"=
http://www.connettivo.net/cntprojects/ocaml_beginners">http://www.connettiv=
o.net/cntprojects/ocaml_beginners</a><BR>
The archives of the very official ocaml list (the seniors' one) can be foun=
d at <a href=3D"http://caml.inria.fr">http://caml.inria.fr</a><BR>
Attachments are banned and you're asked to be polite, avoid flames etc.    =
=20=20
<!-- |**|end egp html banner|**| -->

    </div>
=20=20

=20

<!-- |**|begin egp html banner|**| -->
<div id=3D"ygrp-vital" style=3D"background-color: #f2f2f2; font-family: Ver=
dana; font-size: 10px; margin-bottom: 10px; padding: 10px;">

    <span id=3D"vithd" style=3D"font-weight: bold; color: #333; text-transf=
orm: uppercase; "><a href=3D"https://groups.yahoo.com/neo/groups/ocaml_begi=
nners/info;_ylc=3DX3oDMTJlc25kMTloBF9TAzk3MzU5NzE0BGdycElkAzQ5OTkxOTQEZ3Jwc=
3BJZAMxNzA1MDA2NzY0BHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTQ5NTI2NjM2NQ--" style=
=3D"text-decoration: none;">Visit Your Group</a></span>

     <ul style=3D"list-style-type: none; margin: 0; padding: 0; display: in=
line;">
            <li style=3D"border-right: 1px solid #000; font-weight: 700; di=
splay: inline; padding: 0 5px; margin-left: 0;">
      <span class=3D"cat"><a href=3D"https://groups.yahoo.com/neo/groups/oc=
aml_beginners/members/all;_ylc=3DX3oDMTJmZnZnbGZzBF9TAzk3MzU5NzE0BGdycElkAz=
Q5OTkxOTQEZ3Jwc3BJZAMxNzA1MDA2NzY0BHNlYwN2dGwEc2xrA3ZtYnJzBHN0aW1lAzE0OTUyN=
jYzNjU-" style=3D"text-decoration: none;">New Members</a></span>
      <span class=3D"ct" style=3D"color: #ff7900;">1</span>
    </li>
                                              </ul>
  </div>


<div id=3D"ft" style=3D"font-family: Arial; font-size: 11px; margin-top: 5p=
x; padding: 0 2px 0 0; clear: both;">
  <a href=3D"https://groups.yahoo.com/neo;_ylc=3DX3oDMTJkcGVjNmJhBF9TAzk3ND=
c2NTkwBGdycElkAzQ5OTkxOTQEZ3Jwc3BJZAMxNzA1MDA2NzY0BHNlYwNmdHIEc2xrA2dmcARzd=
GltZQMxNDk1MjY2MzY1" style=3D"float: left;"><img src=3D"http://l.yimg.com/r=
u/static/images/yg/img/email/new_logo/logo-groups-137x15.png" height=3D"15"=
 width=3D"137" alt=3D"Yahoo! Groups" style=3D"border: 0;"/></a>
  <div style=3D"color: #747575; float: right;"> &bull; <a href=3D"https://i=
nfo.yahoo.com/privacy/us/yahoo/groups/details.html" style=3D"text-decoratio=
n: none;">Privacy</a> &bull; <a href=3D"mailto:ocaml_beginners-unsubscribe@=
yahoogroups.com?subject=3DUnsubscribe" style=3D"text-decoration: none;">Uns=
ubscribe</a> &bull; <a href=3D"https://info.yahoo.com/legal/us/yahoo/utos/t=
erms/" style=3D"text-decoration: none;">Terms of Use</a> </div>
</div>
<br>

<!-- |**|end egp html banner|**| -->

  </div> <!-- ygrp-msg -->

=20
  <!-- Sponsor -->
  <!-- |**|begin egp html banner|**| -->
  <div id=3D"ygrp-sponsor" style=3D"width:160px; float:right; clear:none; m=
argin:0 0 25px 0; background: #fff;">

<!-- Start Recommendations -->
<div id=3D"ygrp-reco">
     </div>
<!-- End Recommendations -->



  </div>   <!-- |**|end egp html banner|**| -->

  <div style=3D"clear:both; color: #FFF; font-size:1px;">.</div>
</div>

  <img src=3D"http://geo.yahoo.com/serv?s=3D97359714/grpId=3D4999194/grpspI=
d=3D1705006764/msgId=3D14811/stime=3D1495266365" width=3D"1" height=3D"1"> =
<br>

<img src=3D"http://y.analytics.yahoo.com/fpc.pl?ywarid=3D515FB27823A7407E&a=
=3D10001310322279&js=3Dno&resp=3Dimg&cf12=3DCP" width=3D"1" height=3D"1">=20

<div style=3D"color: #fff; height: 0;">__,_._,___</div>
<!--~-|**|PrettyHtmlEnd|**|-~-->

</body>

<!--~-|**|PrettyHtmlStart|**|-~-->
<head>
  <style type=3D"text/css">
  <!--
  #ygrp-mkp {
  border: 1px solid #d8d8d8;
  font-family: Arial;
  margin: 10px 0;
  padding: 0 10px;
}

#ygrp-mkp hr {
  border: 1px solid #d8d8d8;
}

#ygrp-mkp #hd {
  color: #628c2a;
  font-size: 85%;
  font-weight: 700;
  line-height: 122%;
  margin: 10px 0;
}

#ygrp-mkp #ads {
  margin-bottom: 10px;
}

#ygrp-mkp .ad {
  padding: 0 0;
}

#ygrp-mkp .ad p {
  margin: 0;
}

#ygrp-mkp .ad a {
  color: #0000ff;
  text-decoration: none;
}
  #ygrp-sponsor #ygrp-lc {
  font-family: Arial;
}

#ygrp-sponsor #ygrp-lc #hd {
  margin: 10px 0px;
  font-weight: 700;
  font-size: 78%;
  line-height: 122%;
}

#ygrp-sponsor #ygrp-lc .ad {
  margin-bottom: 10px;
  padding: 0 0;
}

  #actions {
    font-family: Verdana;
    font-size: 11px;
    padding: 10px 0;
  }

  #activity {
    background-color: #e0ecee;
    float: left;
    font-family: Verdana;
    font-size: 10px;
    padding: 10px;
  }

  #activity span {
    font-weight: 700;
  }

  #activity span:first-child {
    text-transform: uppercase;
  }

  #activity span a {
    color: #5085b6;
    text-decoration: none;
  }

  #activity span span {
    color: #ff7900;
  }

  #activity span .underline {
    text-decoration: underline;
  }

  .attach {
    clear: both;
    display: table;
    font-family: Arial;
    font-size: 12px;
    padding: 10px 0;
    width: 400px;
  }

  .attach div a {
    text-decoration: none;
  }

  .attach img {
    border: none;
    padding-right: 5px;
  }

  .attach label {
    display: block;
    margin-bottom: 5px;
  }

  .attach label a {
    text-decoration: none;
  }
=20=20
  blockquote {
    margin: 0 0 0 4px;
  }

  .bold {
    font-family: Arial;
    font-size: 13px;
    font-weight: 700;
  }

  .bold a {
    text-decoration: none;
  }

  dd.last p a {
    font-family: Verdana;
    font-weight: 700;
  }

  dd.last p span {
    margin-right: 10px;
    font-family: Verdana;
    font-weight: 700;
  }

  dd.last p span.yshortcuts {
    margin-right: 0;
  }

  div.attach-table div div a {
    text-decoration: none;
  }

  div.attach-table {
    width: 400px;
  }

  div.file-title a, div.file-title a:active, div.file-title a:hover, div.fi=
le-title a:visited {
    text-decoration: none;
  }

  div.photo-title a, div.photo-title a:active, div.photo-title a:hover, div=
.photo-title a:visited {
    text-decoration: none;
  }

  div#ygrp-mlmsg #ygrp-msg p a span.yshortcuts {
    font-family: Verdana;
    font-size: 10px;
    font-weight: normal;
  }

  .green {
    color: #628c2a;
  }

  .MsoNormal {
    margin: 0 0 0 0;
  }

  o {
    font-size: 0;
  }

  #photos div {
    float: left;
    width: 72px;
  }

  #photos div div {
    border: 1px solid #666666;
    height: 62px;
    overflow: hidden;
    width: 62px;
  }

  #photos div label {
    color: #666666;
    font-size: 10px;
    overflow: hidden;
    text-align: center;
    white-space: nowrap;
    width: 64px;
  }

  #reco-category {
    font-size: 77%;
  }

  #reco-desc {
    font-size: 77%;
  }

  .replbq {
    margin: 4px;
  }

  #ygrp-actbar div a:first-child {
   /* border-right: 0px solid #000;*/
    margin-right: 2px;
    padding-right: 5px;
  }

  #ygrp-mlmsg {
    font-size: 13px;
    font-family: Arial, helvetica,clean, sans-serif;
    *font-size: small;
    *font: x-small;
  }

  #ygrp-mlmsg table {
    font-size: inherit;
    font: 100%;
  }

  #ygrp-mlmsg select, input, textarea {
    font: 99% Arial, Helvetica, clean, sans-serif;
  }

  #ygrp-mlmsg pre, code {
    font:115% monospace;
    *font-size:100%;
  }

  #ygrp-mlmsg * {
    line-height: 1.22em;
  }

  #ygrp-mlmsg #logo {
    padding-bottom: 10px;
  }


  #ygrp-msg p a {
    font-family: Verdana;
  }

  #ygrp-msg p#attach-count span {
    color: #1E66AE;
    font-weight: 700;
  }

  #ygrp-reco #reco-head {
    color: #ff7900;
    font-weight: 700;
  }

  #ygrp-reco {
    margin-bottom: 20px;
    padding: 0px;
  }

  #ygrp-sponsor #ov li a {
    font-size: 130%;
    text-decoration: none;
  }

  #ygrp-sponsor #ov li {
    font-size: 77%;
    list-style-type: square;
    padding: 6px 0;
  }=20

  #ygrp-sponsor #ov ul {
    margin: 0;
    padding: 0 0 0 8px;
  }

  #ygrp-text {
    font-family: Georgia;
  }

  #ygrp-text p {
    margin: 0 0 1em 0;
  }

  #ygrp-text tt {
    font-size: 120%;
  }

  #ygrp-vital ul li:last-child {
    border-right: none !important;=20
  }=20
  -->
  </style>
</head>

<!--~-|**|PrettyHtmlEnd|**|-~-->
</html>
<!-- end group email -->


--001a11417d0ee85c94054fefc061--