I'm learning Haskell and writing a program to solve a toy problem. The program uses a parameter k that doesn't change while it is running, after the parameter has been read from a file. I'm very new to using pure functions, and I would like to write as many functions as pure ones as I can.
I have a data type Node
, and functions to compare nodes, get the descendants of nodes, and more. Currently, all of these functions take a parameter k as an argument, such as
compare k node1 node2 = ...
desc k node = ...
and whenever I have to recursively call any of these within the function, I have to repeat the k parameter. It seems redundant, since k will never have a different value for these functions and since it makes the type signatures less readable, and I would like to refactor it out if possible.
Are there any strategies to do this with pure functions, or is it simply a limitation I'll have to deal with?
What I've thought of
Earlier I hard-coded k at the top level, and it seemed to work (I was able to use k in the functions without needing it as an explicit argument). But this obviously wasn't feasible once I needed to read input from file.
Another possible strategy would be to define all these functions in the main
function, but this seems to be strongly discouraged in Haskell.
Ultimately you have to pass in the value of k
everywhere it is needed, but there are some things you can do to avoid repeating it.
One thing you can do is to define convenience functions once the value of k
is known:
myfunc = let k = ...
compare' = compare k
desc' = desc k
in ...
(use compare' and desc' here)
Another approach is to use the Implicit Parameters extension. This involves defining compare
and desc
to take k
as an implicit parameter:
{-# LANGUAGE ImplicitParameters #-}
compare :: (?k :: Int) => Node -> Node
compare n1 n2 = ... (can use ?k here) ...
desc :: (?k :: Int) => Node
desc = ... (can use ?k here) ...
myfunc = let ?k = ...
in ... use compare and desc ...
Note that in either case you can't call compare
or desc
until you've defined what k
is.