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