Reputation: 475
I often find myself writing multiple functions with the same type. Let's call this type FuncType
. I might write something like this:
funcA :: FuncType
funcB :: FuncType
funcC :: FuncType
funcD :: FuncType
-- Implementations
This feels like a lot of unnecessary typing (typing as in tapping on the keyboard, not declaring types of functions). Is there maybe some way to do this more concisely? What I want would look something along the lines of:
(funcA, funcB, funcC, funcD) :: FuncType
-- Implementations
I really tried to google this but I came up empty. If this isn't a feature of the language, why not? Am I missing something? Am I doing something wrong if I find myself needing this?
Upvotes: 13
Views: 1185
Reputation: 7266
Alternatively to MasterMastic's answer, you can also actually give the repeated type a name using a type declaration:
-- | why GoodName is a good name
type GoodName = Complicated -> Function -> Type
-- | Foo explanation.
foo :: GoodName
foo = ...
-- | Bar explanation.
bar :: GoodName
bar = ...
This way, you only need to repeat the name instead of the potentially much longer type. Benefits of this style over foo, bar :: Complicated -> Function -> Type
include:
Of course, you can also combine these approaches as foo, bar :: GoodName
. Because of type inference, you can usually even leave out the type signature altogether and let the compiler figure out the type.
Upvotes: 4
Reputation: 21306
Do what you tried without the parentheses.
funcA, funcB, funcC, funcD :: FuncType
In the Haskell 2010 report, you can see in chapter 4 (Declarations and Bindings) that a type signature (gendecl
) looks like this:
vars :: [context =>] type
and vars
look like this:
var-1 , … , var-n
Which is exactly the form you're looking for.
Sidenote: Haddock will apply a documentation if it finds it around that type signature to every symbol in that (vars
) list.
Upvotes: 18