Skip to content

Instantly share code, notes, and snippets.

@cem2ran
Last active May 15, 2017 03:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cem2ran/fff17df113eccb41e370 to your computer and use it in GitHub Desktop.
Save cem2ran/fff17df113eccb41e370 to your computer and use it in GitHub Desktop.

##Monads for functional programming (in Elm)

Adaptation of the examples in Philip Wadler's paper "Monads for functional programming" for the Elm language.

These examples can easily be tried out on the online elm playground: http://elm-lang.org/try

import Html exposing (text)
import Text
type Term = Con Int
| Div Term Term
eval : Term -> Int
eval term =
case term of
Con a -> a
Div t u -> eval t // eval u
main =
text (toString (eval (Div(Div(Con 1972)(Con 2))(Con 23))))
import Html exposing (text)
import Text
type Term = Con Int
| Div Term Term
type M a = Raise Exception | Return a
type alias Exception = String
eval : Term -> M Int
eval term =
case term of
Con a -> Return a
Div t u -> case eval t of
Raise e -> Raise e
Return a ->
case eval u of
Raise e -> Raise e
Return b ->
if b==0
then Raise "divide by zero"
else Return (a // b)
main =
text (toString (eval (Div(Div(Con 1972)(Con 2))(Con 0))))
import Html exposing (text)
import Text
type Term = Con Int
| Div Term Term
type alias M a = State -> (a,State)
type alias State = Int
eval : Term -> M Int
eval term =
case term of
Con a -> \x -> (a,x)
Div t u -> \x ->
let (a,y) = eval t x in
let (b,z) = eval u y in
(a//b,z+1)
main = text (toString (eval (Div(Div(Con 1972)(Con 2))(Con 23)) 0))
import Html exposing (text)
import Text
type Term = Con Int
| Div Term Term
type alias M a = (Output, a)
type alias Output = String
eval : Term -> M Int
eval term =
case term of
Con a -> (line (Con a) a, a)
Div t u -> let (x,a) = (eval t) in
let (y,b) = (eval u) in
let division = a//b in
(x ++ y ++ line(Div t u)(division), division)
line : Term -> Int -> Output
line t a = "eval(" ++ (toString t) ++ ") <= " ++ (toString a)
(output, result) = (eval (Div(Div(Con 1972)(Con 2))(Con 23)))
main = text (toString output)
import Html exposing (text)
import Text
type Term = Con Int
| Div Term Term
type M a = Raise Exception | Return a
type alias Exception = String
unit : a -> M a
unit a = Return a
flatMap : M a -> (a -> M b) -> M b
flatMap a k = case a of
Raise e -> Raise e
Return a -> k a
eval : Term -> M Int
eval term =
case term of
Con a -> unit a
Div t u ->
flatMap (eval t)(\a ->
flatMap (eval u)(\b ->
if b == 0
then Raise "divide by zero"
else unit (a//b)
)
)
main = text (toString (eval (Div(Div(Con 1972)(Con 2))(Con 0))))
import Html exposing (text)
import Text
type Term = Con Int
| Div Term Term
type M a = Raise Exception | Return a
type alias Exception = String
unit : a -> M a
unit a = Return a
flatMap : M a -> (a -> M b) -> M b
flatMap a k = case a of
Raise e -> Raise e
Return a -> k a
eval : Term -> M Int
eval term =
case term of
Con a -> unit a
Div t u -> flatMap (eval t)
<| \a -> flatMap (eval u)
<| \b -> if b == 0
then Raise "divide by zero"
else unit (a//b)
main = text (toString (eval (Div(Div(Con 1972)(Con 2))(Con 0))))
import Html exposing (text)
import Text
type Term = Con Int
| Div Term Term
type alias M a = State -> (a,State)
type alias State = Int
unit : a -> M a
unit a = \x -> (a,x)
flatMap : M a -> (a -> M b) -> M b
flatMap m k = \x ->
let (a,y) = m x in
let (b,z) = k a y in
(b,z)
eval : Term -> M Int
eval term =
case term of
Con a -> unit a
Div t u ->
flatMap (eval t)(\a ->
flatMap (eval u)(\b ->
flatMap(tick)(\()->
unit(a//b)
)
)
)
tick : M ()
tick = \x -> ((), x+1)
main = text (toString (eval (Div(Div(Con 1972)(Con 2))(Con 23)) 0))
import Html exposing (text)
import Text
type Term = Con Int
| Div Term Term
type alias M a = (Output, a)
type alias Output = String
unit : a -> M a
unit a = ("", a)
flatMap : M a -> (a -> M b) -> M b
flatMap m k =
let (x,a) = m in
let (y,b) = k a in
(x++y, b)
eval : Term -> M Int
eval term =
case term of
Con a -> flatMap (out(line(Con a) a)) (\() -> unit(a))
Div t u ->
flatMap (eval t)(\a ->
flatMap (eval u)(\b ->
flatMap(out(line(Div t u)(a//b))) (\() -> unit(a//b))
)
)
out : Output -> M ()
out x = (x, ())
line : Term -> Int -> Output
line t a = "eval(" ++ (toString t) ++ ") <= " ++ (toString a)
main = text (toString (eval (Div(Div(Con 1972)(Con 2))(Con 23))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment