2015-03-26 2 views
2

Если бы я хотел, чтобы создать новый тип в C++, в котором я перегружать кучу операторов я могу сделать что-то вроде:Инкапсуляция пользовательского типа Haskell со всеми операциями в один класс

class Stringy { 
    public: 
    explict Stringy(const char *buffer){} 
    friend Stringy operator + (const Stringy &s1, const Stringy &s2) { ... } 
    friend Stringy operator - (const Stringy &s1, const Stringy &s2) { ... } 
    friend std::ostream& operator << (std::ostream &oss, const String& s1) { ... } 
}; 

Теперь если я попытаюсь сделать то же самое в Haskell, я считаю себя делать (пример):

data Stringy = Stringy([Char]) 
-- do something unrelated here -- 
(+) :: Stringy -> Stringy -> Stringy 
(-) :: Stringy -> Stringy -> Stringy 
(removeDups) :: Stringy -> Stringy 
-- do something else unrelated here -- 
(>>) :: Stringy -> IO --(is IO right?) 

Моя точка является то, что C++ один выглядит положить вместе, потому что все, что вы делаете внутри этого класса относится в некотором роде к классу. С другой стороны, объявления операторов для haskell могут быть повсюду и не обязательно должны быть вместе. Если кто-то взглянет на код C++, они смогут сразу определить, какие операции являются частью класса, а какие нет. Как я мог бы достичь такой же однородности в Haskell?

Я все еще новичок в Haskell, поэтому, пожалуйста, просто используйте простой способ делать вещи. Спасибо

+1

Если вы хотите знать все способы использования типа в одном месте, [haddock] (https://www.haskell.org/haddock/) хорошо справляется с созданием этой документации. Например, если вы посмотрите на документацию для ['Proxy'] (https://hackage.haskell.org/package/pipes-4.1.4/docs/Pipes-Core.html#t:Proxy) из труб, вы могут видеть в разделе ** Экземпляры **, что «Прокси» может использоваться многими разными способами вне функций с новыми именами, определенными только для прокси. Функции, которые работают с типом и поставляются с типом, обычно будут находиться в * пространстве имен *, посвященном этому типу. – Cirdec

+1

А как насчет того, чтобы все материалы 'Stringy' были в модуле' Stringy.sh'? – wowofbob

+0

@wowofbob, это эквивалент '.h' файлов в C++? Если так спасибо, я посмотрю, что в более позднее время, но я не думаю, что несколько файлов решат проблему. – smac89

ответ

1

Как сказал Дэниел, хорошие дизайнеры библиотеки стараются связать функциональные возможности в одном модуле. Таким образом, типичный тип Stringy и все «основные» операции на Stringy s будут в модуле Stringy (или X.Y.Z.Stringy), в файле Stringy.hs.

В конце концов, я думаю, вы придете, чтобы оценить гибкость, которую дает вам Хаскелл. Например, предположим, что вы хотите, чтобы определить функцию с типом

myfunction :: Stringy -> Thingy -> Doohicky 

Это не очень вписывается ни в одну из трех классов типов (Stringy, Thingy или Doohicky), поскольку он ссылается на типы, которые не являются часть класса. Возможно, эти три типа очков состоят из трех отдельных модулей, давно написанных разными людьми. Вы тот, кто понял, что полезной может быть myFunction. Haskell позволяет поместить эту функцию, если вы считаете, что она имеет наибольший смысл. Вы можете создать совершенно новый модуль, посвященный способам создания Doohicky s из сочетаний значений других типов.

Смежные вопросы