the other day I wrote a small program to collect a bunch of numbers in a matrix - data Matrix = Matrix [[Int]] starting at a corner - Corner and follow a Path - [Direction] all of the three types are instance of a class Transformable
then i have a function that generates a transformation function, that turns a given corner and direction - to LeftUp and Right
turnLUR :: Transformable a => (Corner, Direction) -> a -> a
then i use this function to "harvest" all the numbers in the matrix:
harvest :: Matrix → [(Corner,Direction)] → [Int]
harvest _ [] = []
harvest (Matrix []) _ = []
harvest as (cd:csds) = b ++ harvest (Matrix bs) csds'  --cd = (Corner,Direction)
                     where f1 = turnLUR cd -- Matrix -> Matrix
                           f2 = turnLUR cd -- Corner -> Corner
                           f3 = turnLUR cd -- Direction -> Direction
                           Matrix (b:bs) = f1 as -- b = first line of [[Int]]
                           fcfd (c,d) = (f2 c,f3 d)
                           csds' = map fcfd csds
Now my question why do I have to write down f1, f2 and f3 instead of using one function f three times (keeping DRY in my mind!) - all three types Corners, Directions and Matrix are instances of the class Transformable.
How would I write that code without - making three versions of the "same" function?
This is because of the monomorphism restriction. Give it an explicit type signature, and you'll be able to reuse the same function each time:
harvest :: Matrix → [(Corner,Direction)] → [Int]
harvest _ [] = []
harvest (Matrix []) _ = []
harvest as (cd:csds) = b ++ harvest (Matrix bs) csds'  --cd = (Corner,Direction)
                     where f :: Transformable a => a -> a
                           f = turnLUR cd
                           Matrix (b:bs) = f as -- b = first line of [[Int]]
                           fcfd (c,d) = (f c,f d)
                           csds' = map fcfd csds
Alternatively, you can turn it off by putting {-# LANGUAGE NoMonomorphismRestriction #-} at the top of your file.
The monomorphism restriction isn't well-liked — even GHC's manual refers to it as the dreaded monomorphism restriction — but there are some tricky corner cases, especially related to sharing (see the wiki page I linked for more information), that it avoids. In this case, I'd recommend just adding the type signature.
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