I was wondering how to check whether a string is a pangram, as a beginner's exercise. I have two solutions, but I don't understand them at all.
Version 1
import Data.Char (toLower)
isPangram :: String -> Bool
isPangram str = all (`elem` map toLower str) ['a'..'z']
Version 2
import Data.Char (toLower)
isPangram :: String -> Bool
isPangram str = allPresent (map toLower str) ['a'..'z']
allPresent :: String -> String -> Bool
allPresent _ [] = True
allPresent [] _ = False
allPresent (x:xs) ys
| x `elem` ys = allPresent xs ys
| otherwise = False
Not sure if they're correct, but any help to simplify or modify this would be appreciated!
Your second version is not. That should be:
Indeed, for a pangram you check if all characters belong to the string. But that is not symmetrical: checking if all elements of X belong to Y is not equivalent to checking if all elements of Y belong to X. We here thus use the first list as the collection of items where we check if each item
xof that collection, is an element of the second collectionys.We thus call
allPresent ['a' .. 'z'] (map toLower str)so the first list contains all lowercase characters, the second the lowercase version of the inputstr. In case the first list is empty, we are done, so we can returnTrue. In case it is not, and the second list is empty, we know it will beFalse. If both lists are not empty, we check if the first itemxof the list is a member ofys, and if so recurse with the rest of the elementsxs; otherwise we can returnFalse.