For teaching Haskell to beginners using the recent version of GHC, the types of some functions can be confusing due to the Foldable-Traversable-in-Prelude (FTP). For example, basic functions on lists such as length
, sum
and product
have types that include the Foldable
constraint foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
. Similarly for some introductory higher order functions e.g. foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
.
What is a lightweight way of temporarily enabling pre-FTP behaviour? Then beginners can still enjoy all the benefits of a recent GHC, and don't have to resort to trying to install older versions, or using Hugs (e.g. as suggested for edX's FP101x 2015 edition).
That could work fine, but we decided to go with something less tedious for http://haskellbook.com/, what we did was we explained what changed and show them how you could assert the list-based type.
Prelude> :t length
length :: Foldable t => t a -> Int
Prelude> :t length :: [a] -> Int
length :: [a] -> Int
Between that and the types asserted in the examples & exercises, this has sufficed and if they accidentally encounter a type with Foldable in it, it doesn't cause trouble because we've told them how things changed.
Making them import stuff and not bothering to tell them what happened seems brittle, as they'll get confused if they get off the happy path.
One option demonstrated as follows:
$ ghci
Prelude> import Prelude hiding (length, sum, product, foldr, foldl, and, or, any, all)
Prelude> import GHC.OldList
Prelude GHC.OldList>
Then you get the old types for everything that was hidden, e.g.
length :: [a] -> Int
sum :: Num a => [a] -> a
product :: Num a => [a] -> a
foldr :: (a -> b -> b) -> b -> [a] -> b
foldl :: (b -> a -> b) -> b -> [a] -> b
and :: [Bool] -> Bool
any :: (a -> Bool) -> [a] -> Bool
all :: (a -> Bool) -> [a] -> Bool
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With