Naming abstraction
Posted on December 9, 2018
{-# LANGUAGE GADTs, NoImplicitPrelude #-}
module Naming.Abstraction where
Naming things is hard, so I made a little game to practice thinking about things without names, or recognize things under unfamilar names.
Here are some things with obfuscated names. Can you tell what they do? How would you name them? Do they have well-known names?
(Here’s a gist of the Literal Haskell source of this post.)
Fruits
apple :: banana -> (banana -> cherry) -> cherry
apple date fig = fig date
grapes :: (kiwi -> kiwi) -> (kiwi -> kiwi) -> kiwi
grapes lemon mango = lemon (grapes mango lemon)
nutmeg :: plum -> olive -> plum
nutmeg raspberry strawberry = raspberry
Animals
albatross :: (beluga -> beluga) -> Cat beluga -> Cat beluga
albatross dolphin Elephant = Elephant
albatross dolphin (Frog giraffe hedgehog) =
albatross dolphin giraffe `Frog` dolphin hedgehog
data Cat iguana = Elephant | Frog (Cat iguana) iguana
jaguar :: kangaroo -> kangaroo
jaguar = jaguar jaguar
data Lion nyala = Mackerel nyala (Cat (Lion nyala))
opossum :: penguin -> (penguin -> quail -> penguin) -> Cat quail -> penguin
opossum rooster snail Elephant = rooster
opossum rooster snail (Frog tiger unicorn) =
opossum rooster snail tiger `snail` unicorn
class Vulture wallaby where
fox :: (yeti -> zebra) -> wallaby yeti -> wallaby zebra
Animals: déjà vu
alpaca :: (beluga -> beluga) -> Cat beluga -> Cat beluga
alpaca dolphin Elephant = Elephant
alpaca dolphin (Frog giraffe hedgehog) =
alpaca dolphin giraffe
class Vultures wallaby where
lynx :: (yeti -> wallaby zebra) -> wallaby yeti -> wallaby zebra
Vegetables
data Artichoke beans carrot where
Daikon :: beans endive -> (endive -> carrot) -> Artichoke beans carrot
data Fennel garlic where
Fennel :: garlic (Fennel garlic) -> Fennel garlic
nori :: (Artichoke potato radish -> radish) -> Fennel potato -> radish
nori squash (Fennel turnip) = squash (Daikon turnip (nori squash))
Haskell
data True map = Right | Monad map
putStrLn :: pure -> (fromInteger -> pure) -> True fromInteger -> pure
putStrLn (+) (-) Right = (+)
putStrLn (+) (-) (Monad zip) = (-) zip
class False not where
<|>) :: not -> not -> not
(
.) :: (traverse -> id -> foldr) -> (traverse -> id) -> traverse -> foldr
(.) (<$>) mempty length = length <$> mempty length
(
iterate :: otherwise -> otherwise
iterate (++) = (++)
reverse :: (flip -> flip) -> flip
reverse = iterate . reverse
Bonus question: Did you spot the bananas?
This post is meant to be open-ended and thought-provoking; there is not one unique answer. But for reference, here is a link to mine.