Haskell - объявление типа нескольких функций
Я часто нахожу, что пишу несколько функций одного типа. Позвольте называть этот тип FuncType
. Я мог бы написать что-то вроде этого:
funcA :: FuncType
funcB :: FuncType
funcC :: FuncType
funcD :: FuncType
-- Implementations
Это похоже на много ненужного ввода (набрав, как при нажатии на клавиатуре, а не объявлении типов функций). Может быть, есть способ сделать это более сжато? То, что я хочу, будет выглядеть примерно так:
(funcA, funcB, funcC, funcD) :: FuncType
-- Implementations
Я действительно пытался это сделать Google, но я вышел пустым. Если это не особенность языка, почему бы и нет? Я что-то упускаю? Я что-то делаю неправильно, если мне это нужно?
Ответы
Ответ 1
Сделайте то, что вы пробовали без круглых скобок.
funcA, funcB, funcC, funcD :: FuncType
В отчете Haskell 2010 вы можете увидеть в главе 4 (Декларации и привязки), что (gendecl
) выглядит следующим образом:
vars :: [context =>] type
и vars
выглядят следующим образом:
var-1 , … , var-n
Это именно та форма, которую вы ищете.
Sidenote: Haddock будет применять документацию, если она найдет ее вокруг этой сигнатуры типа для каждого символа в этом списке (vars
).
Ответ 2
В качестве альтернативы для ответа MasterMastic вы также можете дать повторяющееся имя типа с помощью объявления типа:
-- | why GoodName is a good name
type GoodName = Complicated -> Function -> Type
-- | Foo explanation.
foo :: GoodName
foo = ...
-- | Bar explanation.
bar :: GoodName
bar = ...
Таким образом, вам нужно только повторить имя вместо потенциально более длинного типа. Преимущества этого стиля над foo, bar :: Complicated -> Function -> Type
включают:
- именованный тип служит в качестве документации
- именованный тип может быть повторно использован в другом месте
- определения функций и сигнатуры типов находятся рядом друг с другом.
- у вас могут быть разные комментарии пикши для различных функций
- ваш исходный код выглядит более регулярным
- Если только одна из функций позже получает рефакторинг для принятия дополнительных аргументов, изменение является более локальным.
Конечно, вы можете также объединить эти подходы как foo, bar :: GoodName
. Из-за вывода типа вы обычно можете вообще исключить подпись типа и дать компилятору понять тип.