What are side-effects but undocumented arguments and returns?
Firstly, you want to ensure your functions are pure with respect to input. That is to say, they might reference a configuration or context object that is passed to them as an argument, but they'll never reference some global object/variable.
So then the docker image inside some docker registry? Both the image and the registry are values in the config/context argument at the least. Maybe they're their own separate arguments depending on whether you prefer a single big object argument or a bunch of smaller more primitive arguments.
So then the pure function that expects the docker image to exist in some registry is no longer
Int -> Int
It's now
String -> String -> Int -> Int
because it needs a registry and an image. Maybe it's
String -> String -> String -> String -> Int -> Int
because there's a username and password required to access the registry. Icky, but if we make a few types like
data Registry {
user :: String,
password :: String,
url :: String
}
that becomes
Registry -> String -> Int
But we could make it better by doing something like
data Foo {
reg:: Registry,
image :: String
}
and now the function can be
Foo -> Int -> Int
This doesn't fix the image not actually existing in the registry, but at least now we know that the two functions aren't composable, and when it fails because the image doesn't exist we can hopefully trace through to see who the caller is that's giving it incorrect data.
PS: sorry if i got the haskell typing wrong. I don't know haskell so that's the result of what i could cobble together from googling about haskell type syntax
Firstly, you want to ensure your functions are pure with respect to input. That is to say, they might reference a configuration or context object that is passed to them as an argument, but they'll never reference some global object/variable.
So then the docker image inside some docker registry? Both the image and the registry are values in the config/context argument at the least. Maybe they're their own separate arguments depending on whether you prefer a single big object argument or a bunch of smaller more primitive arguments.
So then the pure function that expects the docker image to exist in some registry is no longer
It's now because it needs a registry and an image. Maybe it's because there's a username and password required to access the registry. Icky, but if we make a few types like that becomes But we could make it better by doing something like and now the function can be This doesn't fix the image not actually existing in the registry, but at least now we know that the two functions aren't composable, and when it fails because the image doesn't exist we can hopefully trace through to see who the caller is that's giving it incorrect data.PS: sorry if i got the haskell typing wrong. I don't know haskell so that's the result of what i could cobble together from googling about haskell type syntax