I hope my terminology is correct here - if not, feel free to edit anything.
I'm using Haskell as a helper-language whilst writing a paper on combinatorial game theory - i.e., all of my functions just juggle numbers and help me to come to a solution for the game I'm studying.
I wrote all of the functions for a concrete, integral 'board size' (think chequerboard, 5x5 etc). I wanted to expand to study boards of any size, so modified all the relevant functions by including an Integer parameter. e.g.,
type Size = Int
squares :: Size -> [Square]
squares size = [ (x,y) | x <- [1..size],
y <- [1..size]]
This, however, has started to get messy. Functions which normally I would consider size-independent have to be supplied with a Size whenever they access a function which requires a Size.
This very quickly leads to lines like this:
reaching size = (losing size) \\\ (setA size)
takeUDmir _ [] = []
takeUDmir size (x:xs) = [x] ++ takeUDmir size (xs \\\ mirUD size x)
rotate size s = concatMap (mirUD size) (mirLR size s)
(Note that the content of the functions really doesn't matter, I'm just trying to show how out-of-hand it has become.)
I'm pretty confident using Haskell, and with functional programming in general, but I've got no idea how I could go about removing all of these size
references, and simply relying on something else which sets the size for each function which requires its use.
I think I'm probably looking for a monad, but I've got no idea.
In Haskell, all functions are considered curried: That is, all functions in Haskell take just one argument. This is mostly hidden in notation, and so may not be apparent to a new Haskeller.
No. However, you can have functions that return a trivial value.
This is a perfect time to pull out the Reader
monad—it abstracts the notion of some globally available, read-only configuration data.
data Config = Config { size :: Int, ... }
type MyMonad = Reader Config
fun :: MyMonad Result
fun = funNeedingTheSize <$> asks size <*> pure arg1 <*> pure arg2
runMyMonad :: Config -> MyMonad a -> a
runMyMonad = flip runReader
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