Created
August 4, 2021 19:42
-
-
Save nabilhassein/def801a9f41a5942135827a677afc7e4 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
-- long brute force solution to exercise 7 on p. 20 of "Conceptual Mathematics" | |
-- if you don't have haskell on your computer, paste all this into: | |
-- https://replit.com/languages/haskell | |
-- this is how we define a data type in Haskell. think of it as a set | |
data Bit = Zero | One deriving (Show, Eq) | |
-- the last part tells Haskell to figure out how to print Bits, and that | |
-- Zero equals Zero, One equals One, and Zero is different from One | |
-- this is a type declaration. think domain and codomain | |
identity :: Bit -> Bit | |
-- this is a function definition. the output is always the same as the input | |
identity bit = bit -- bit is a variable. we could have called it "x" | |
-- note the case sensitivity: upper case = types, lower case = something else | |
zero :: Bit -> Bit | |
zero _ = Zero -- this is a function that always gives the same output | |
-- so we don't bother to give a name to the unused variable | |
one :: Bit -> Bit | |
one _ = One | |
-- this function uses "pattern matching" -- like a piecewise function in math | |
bitflip :: Bit -> Bit | |
bitflip Zero = One | |
bitflip One = Zero | |
all_functions :: [Bit -> Bit] | |
all_functions = [identity, zero, one, bitflip] | |
idempotent_functions :: [Bit -> Bit] | |
idempotent_functions = filter is_idempotent all_functions | |
where | |
is_idempotent :: (Bit -> Bit) -> Bool | |
is_idempotent f = f (f Zero) == f Zero && f (f One) == f One | |
main = print (length idempotent_functions) | |
-- you can do the same thing for a type "Ternary" you define to solve exercise 6 | |
-- hard part: hand-writing all 27 possible functions of type Ternary -> Ternary | |
-- i was inspired here by an old abstract algebra homework i got in college | |
-- solution: https://github.com/nabilhassein/exercises/blob/master/Algebra.lhs | |
-- but a better solution than this brute-force method is the formula here: | |
-- https://en.wikipedia.org/wiki/Idempotence#Idempotent_functions |
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
-- boring definitions. i'm sure there's a better generic way to do this | |
-- but 17 isn't too many to brute force ;) | |
data A = John | Mary | Sam deriving (Show, Eq) | |
data B = Eggs | Coffee deriving (Show, Eq) | |
a_to_b_1, a_to_b_2, a_to_b_3, a_to_b_4, a_to_b_5, a_to_b_6, a_to_b_7, a_to_b_8 :: A -> B | |
b_to_a_1, b_to_a_2, b_to_a_3, b_to_a_4, b_to_a_5, b_to_a_6, b_to_a_7, b_to_a_8, b_to_a_9 :: B -> A | |
a_to_b_1 John = Eggs | |
a_to_b_1 Mary = Eggs | |
a_to_b_1 Sam = Eggs | |
a_to_b_2 John = Eggs | |
a_to_b_2 Mary = Eggs | |
a_to_b_2 Sam = Coffee | |
a_to_b_3 John = Eggs | |
a_to_b_3 Mary = Coffee | |
a_to_b_3 Sam = Eggs | |
a_to_b_4 John = Eggs | |
a_to_b_4 Mary = Coffee | |
a_to_b_4 Sam = Coffee | |
a_to_b_5 John = Coffee | |
a_to_b_5 Mary = Eggs | |
a_to_b_5 Sam = Eggs | |
a_to_b_6 John = Coffee | |
a_to_b_6 Mary = Coffee | |
a_to_b_6 Sam = Eggs | |
a_to_b_7 John = Coffee | |
a_to_b_7 Mary = Eggs | |
a_to_b_7 Sam = Coffee | |
a_to_b_8 John = Coffee | |
a_to_b_8 Mary = Coffee | |
a_to_b_8 Sam = Coffee | |
b_to_a_1 Eggs = John | |
b_to_a_1 Coffee = John | |
b_to_a_2 Eggs = John | |
b_to_a_2 Coffee = Mary | |
b_to_a_3 Eggs = John | |
b_to_a_3 Coffee = Sam | |
b_to_a_4 Eggs = Mary | |
b_to_a_4 Coffee = Mary | |
b_to_a_5 Eggs = Mary | |
b_to_a_5 Coffee = John | |
b_to_a_6 Eggs = Mary | |
b_to_a_6 Coffee = Sam | |
b_to_a_7 Eggs = Sam | |
b_to_a_7 Coffee = Sam | |
b_to_a_8 Eggs = Sam | |
b_to_a_8 Coffee = John | |
b_to_a_9 Eggs = Sam | |
b_to_a_9 Coffee = Mary | |
a_to_b_fns :: [A -> B] | |
a_to_b_fns = [a_to_b_1, a_to_b_2, a_to_b_3, a_to_b_4, a_to_b_5, a_to_b_6, a_to_b_7, a_to_b_8] | |
b_to_a_fns :: [B -> A] | |
b_to_a_fns = [b_to_a_1, b_to_a_2, b_to_a_3, b_to_a_4, b_to_a_5, b_to_a_6, b_to_a_7, b_to_a_8, b_to_a_9] | |
-- actual logic | |
a_to_b_to_a_id_pairs :: [A -> A] | |
a_to_b_to_a_id_pairs = filter is_identity [g . f | g <- b_to_a_fns, f <- a_to_b_fns] | |
where | |
is_identity :: (A -> A) -> Bool | |
is_identity func = func John == John && func Mary == Mary && func Sam == Sam | |
b_to_a_to_b_id_pairs :: [B -> B] | |
b_to_a_to_b_id_pairs = filter is_identity [k . h | h <- b_to_a_fns, k <- a_to_b_fns] | |
where | |
is_identity :: (B -> B) -> Bool | |
is_identity func = func Eggs == Eggs && func Coffee == Coffee | |
main = do | |
putStrLn "Answer to exercise 8" | |
print (length a_to_b_to_a_id_pairs) | |
putStrLn "Answer to exercise 9" | |
print (length b_to_a_to_b_id_pairs) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment