Created
July 25, 2022 18:32
-
-
Save arnemileswinter/47cd378d6659280b8465210a5e7d1638 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module MondayTutorial where | |
{- class MyList<T> { | |
private T value; | |
private MyList<T> next; | |
MyList(){} | |
MyList(T value, MyList<T> next){ | |
Objects.requireNonNull(next); | |
this.value = value; | |
this.next = next; | |
} | |
public String show(){ | |
// only if T has Show implementation. | |
if (value != null) { | |
System.out.println( | |
"Cell " + val.show() | |
+ ", " + next.show()); | |
} else { | |
System.out.println("EmptyList"); | |
} | |
} | |
} | |
interface Show { | |
public String show(); | |
} | |
-} | |
data MyList a = EmptyList | |
| Cell a (MyList a) | |
instance Show a => Show (MyList a) where | |
show a = "(" <> show' a <> ")" where | |
show' EmptyList = "EmptyList" | |
show' (Cell val nextList) | |
= "Cell " <> show val | |
<> ", " | |
<> show nextList | |
createSequence :: Int -> MyList Int | |
createSequence 0 = EmptyList | |
createSequence i = Cell (i-1) (createSequence (i-1)) | |
-- increment every element by one. | |
incrementList :: MyList Int -> MyList Int | |
incrementList = mapList (+ 1) | |
listConcat :: MyList a -> MyList a -> MyList a | |
listConcat xs EmptyList = xs | |
listConcat EmptyList ys = ys | |
listConcat (Cell x xs) ys = Cell x (listConcat xs ys) | |
mapList :: (a -> b) -> MyList a -> MyList b | |
mapList _ EmptyList = EmptyList | |
mapList f (Cell x xs) = Cell (f x) (mapList f xs) | |
-- Each element from the second list | |
-- is applied to each function from the first. | |
-- and the results are gathered. | |
applyToEach :: MyList (a -> b) -> MyList a -> MyList b | |
applyToEach EmptyList x = EmptyList | |
applyToEach (Cell f fs) myList = mapList f myList | |
`listConcat` | |
applyToEach fs myList | |
flatMapList :: (a -> MyList b) -> MyList a -> MyList b | |
flatMapList f xs = flattenList $ mapList f xs | |
flattenList :: MyList (MyList b) -> MyList b | |
flattenList EmptyList = EmptyList | |
flattenList (Cell x ys) = listConcat x (flattenList ys) | |
cartesianGrid :: Int -> Int -> MyList (Int,Int) | |
cartesianGrid width height = | |
let tilesX = createSequence width | |
tilesY = createSequence height | |
in (\x -> (\y -> (x+1,y+1)) `mapList` tilesY) `flatMapList` tilesX | |
add :: Int -> (Int -> Int) | |
add x y = x + y | |
addOne :: Int -> Int | |
addOne = add 1 | |
data Option a = None | |
| Some a | |
instance Show a => Show (Option a) where | |
show None = "None" | |
show (Some a) = "Some (" <> show a <> ")" | |
-- mapList :: (a -> b) -> MyList a -> MyList b | |
mapOption :: (a -> b) -> Option a -> Option b | |
mapOption _ None = None | |
mapOption f (Some a) = Some (f a) | |
-- applyToEach :: MyList (Int -> Int) -> MyList Int -> MyList Int | |
applyOption :: Option (a -> b) -> Option a -> Option b | |
applyOption _ None = None | |
applyOption None _ = None | |
applyOption (Some f) (Some x) = Some (f x) | |
-- flatMapList :: (a -> MyList b) -> MyList a -> MyList b | |
flatMapOption :: (a -> (Option b)) -> Option a -> Option b | |
flatMapOption _ None = None | |
flatMapOption f (Some x) = f x | |
-- {Functor} | |
instance Functor Option where | |
fmap = mapOption | |
instance Functor MyList where | |
fmap = mapList | |
-- {Applicative} | |
instance Applicative Option where | |
pure a = Some a | |
(<*>) = applyOption | |
instance Applicative MyList where | |
pure a = Cell a EmptyList | |
(<*>) = applyToEach | |
-- {Monad} | |
instance Monad Option where | |
(>>=) = flip flatMapOption | |
instance Monad MyList where | |
(>>=) = flip flatMapList | |
cartesianGridM :: Int -> Int -> MyList (Int,Int) | |
cartesianGridM width height = createSequence width >>= \x -> | |
createSequence height >>= \y -> | |
return (x+1,y+1) | |
cartesianGridM' :: Int -> Int -> MyList (Int,Int) | |
cartesianGridM' width height = do | |
x <- createSequence width | |
y <- createSequence height | |
return (x,y) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment