Skip to content

Instantly share code, notes, and snippets.

@StevenXL

StevenXL/Cipher.hs

Created Dec 21, 2018
Embed
What would you like to do?
Example usage of Scope Type Variables
{-# LANGUAGE ScopedTypeVariables #-}
module Cipher where
data FourLetterAlphabet = L1 | L2 | L3 | L4 deriving (Show, Enum, Bounded)
-- Because of ScopedTypeVariables, the type variable "a" in the where clause
-- refers to the same type variable "a" as in the function's signature.
--
-- When we apply rotN to a value, all instances of "a" will be instantiated to
-- the type of that value. If we had not used ScopedTypeVariables, then the "a"
-- type variable in the where clause would not be instantiated, and we could not
-- resolve minBound and maxBound.
rotN :: forall a. (Bounded a, Enum a) => a -> a
rotN char = toEnum rotated
where rotated = offset `mod` alphabetSize
offset = fromEnum char + halfAlphabetSize
halfAlphabetSize = alphabetSize `div` 2
alphabetSize = mL [minBound .. maxBound]
mL :: [a] -> Int
mL = length
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.