Skip to content

Instantly share code, notes, and snippets.

@arnemileswinter
Created July 25, 2022 18:32
Show Gist options
  • Save arnemileswinter/47cd378d6659280b8465210a5e7d1638 to your computer and use it in GitHub Desktop.
Save arnemileswinter/47cd378d6659280b8465210a5e7d1638 to your computer and use it in GitHub Desktop.
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