Note that it's polymorphic on the type of the return within the Maybe. It's very flexible, the polymorphic type can appear anywhere within the type signature.
Now you can write various functions that use "read" and they all remain return-type polymorphic. For example, you can write one that loops, requesting the user to repeat entry until parse-able data (of the wanted type) is given:
repeatReadingUntilValid :: Read r => IO r
repeatReadingUntilValid = do
line <- getLine
case read line of
Nothing -> do
putStrLn $ "Invalid input: " ++ show line
repeatReadingUntilValid
Just result ->
return result
That's just a silly example, because read isn't that interesting.
Another example is QuickCheck, which uses type-classes to auto-generate fuzz-testers for functions.
For example:
import Test.QuickCheck
pretty :: MyType -> String
pretty = .. pretty print my type here ..
unpretty :: String -> MyType
unpretty = .. parse the pretty printing of my type here ..
Now I can test that unpretty is indeed the inverse of pretty:
quickCheck (\x -> unpretty (pretty x) == x)
(for every x, the unpretty of pretty of x equals x).
I can generalize this property to:
isInverse f g x = f (g x) == x
And then use:
quickCheck (isInverse unpretty pretty)
Similarly you can define:
commutative f x y = x `f` y == y `f` x
associative f x y z = (x `f` y) `f` z ==
x `f` (y `f` z)
transitive f x y z = x `f` y && y `f` z ==> x `f` z
Which makes an important type of unit testing a breeze.
The type system is saving us from writing code here.
Now you can write various functions that use "read" and they all remain return-type polymorphic. For example, you can write one that loops, requesting the user to repeat entry until parse-able data (of the wanted type) is given:
That's just a silly example, because read isn't that interesting.Another example is QuickCheck, which uses type-classes to auto-generate fuzz-testers for functions.
For example:
Now I can test that unpretty is indeed the inverse of pretty: (for every x, the unpretty of pretty of x equals x).I can generalize this property to:
And then use: Similarly you can define: Which makes an important type of unit testing a breeze.The type system is saving us from writing code here.