Question

Let say I have some constants that I want to name:

foo = 1234
bar = 5678
baz = 1337

By default, the type is Num a => a but wouldn't it be considered good practice to declare types for these constants explicitly?

Doing it like this would be quite verbose:

foo :: Int
foo = 1234

bar :: Int
bar = 5678

baz :: Int
baz = 1337

You could do it like this:

foo, bar, baz :: Int
foo = 1234
bar = 5678
baz = 1337

Which works fine when there aren't too many but when the number of constants increases, you might have to line wrap them and also, it feels like you're repeating yourself.

How about this?:

foo = 1234 :: Int
bar = 5678 :: Int
baz = 1337 :: Int

Would that be considered good style? What's the convention?

Update

Actually, it seems like GHC doesn't consider the last example having any type declarations at all since it warns about "Top-level binding with no type signature".

Was it helpful?

Solution

It depends on why you want all these constants, of course. Personally I would be inclined to give explicit type signatures, yes. If you have a lot of these to declare, I would probably go for

foo = 1234 :: Int
bar = 5678 :: Int
baz = 1337 :: Int

GHC may warn about missing top-level type declarations, but the above bindings are perfectly monomorphic, so you're paying no run-time polymorphism penalty, and the code is clearly readable. (And you can easily add more entries later.)

I might inquire as to why you need to define so many integer constants, and humbly suggest that there may be some more idiomatic way to achieve what you're trying to do - but that would be the subject of another question. For the matter in hand, basically any of the options you've suggested is "fine", but my own personal preference (and that is all it is) would be for the example above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top