Skip to content

Instantly share code, notes, and snippets.

@ObjectBoxPC
Last active July 7, 2020 13:48
Show Gist options
  • Save ObjectBoxPC/7dbdfedc2482d364a41445e5322e54ff to your computer and use it in GitHub Desktop.
Save ObjectBoxPC/7dbdfedc2482d364a41445e5322e54ff to your computer and use it in GitHub Desktop.
Simple Haskell program to check if the input (command-line arguments) form a pangram, containing all 26 letters of the English alphabet
import Data.Char (toUpper)
import Data.List (intercalate)
import Data.List.NonEmpty (NonEmpty, nonEmpty, toList)
import System.Environment (getArgs)
data PangramResult = Pangram | MissingLetters (NonEmpty Char)
checkPangram :: String -> PangramResult
checkPangram s = case nonEmpty missingLetters of
Just ls -> MissingLetters ls
Nothing -> Pangram
where
missingLetters = filter (not . (`elem` normalized)) ['A'..'Z']
normalized = map toUpper s
getText :: IO String
getText = concat <$> getArgs
showLetters :: NonEmpty Char -> String
showLetters = intercalate ", " . map (:[]) . toList
main = do
text <- getText
let
message = case checkPangram text of
Pangram -> "Pangram"
MissingLetters ls -> "Not a pangram: Missing " ++ showLetters ls
putStrLn message
@friedbrice
Copy link

friedbrice commented Jul 6, 2020

@ObjectBoxPC I'm glad it was helpful. I definitely relate to the tendency to want to write your main as a pipeline, so I tend to favor the putStrLn . msg . concat =<< getArgs style. It never bothered me that the entrance to the pipeline is on the right side, because that's how function application is written in every programming language and traditionally on paper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment