Синтаксис записи в Haskell и классы типов

Вы можете сделать это, используя конвейер агрегации, но это боль, чтобы написать его самостоятельно.

Вы можете использовать mongo-join-query , чтобы автоматически создать конвейер агрегации из вашего запроса.

Так будет выглядеть ваш запрос:

const mongoose = require("mongoose");
const joinQuery = require("mongo-join-query");

joinQuery(
    mongoose.models.Comment,
    {
        find: { pid:444 },
        populate: ["uid"]
    },
    (err, res) => (err ? console.log("Error:", err) : console.log("Success:", res.results))
);

Ваш результат будет иметь пользовательский объект в поле uid, и вы можете связать столько уровней, сколько хотите. Вы можете заполнить ссылку на пользователя, которая ссылается на команду, которая ссылается на что-то еще и т. Д.

Отказ от ответственности: я написал mongo-join-query для решения этой точной проблемы.

14
задан Clint Miller 13 December 2009 в 21:04
поделиться

4 ответа

You want extensible records which, I gather, is one of the most talked about topics in Haskell. It appears that there is not currently much consensus on how to implement it.

In your case it seems like maybe instead of an ordinary record you could use a heterogeneous list like those implemented in HList.

Then again, it seems you only have two levels here: common and program. So maybe you should just define a common record type for the common options and a program-specific record type for each program, and use StateT on a tuple of those types. For the common stuff you can add aliases that compose fst with the common accessors so it's invisible to callers.

5
ответ дан 1 December 2019 в 15:02
поделиться

You could use code such as

data Foo = Foo { fooX :: Int, fooY :: Int } deriving (Show)
data Bar = Bar { barX :: Int, barZ :: Int } deriving (Show)

instance HasX Foo where
  getX = fooX
  setX r x' = r { fooX = x' }

instance HasX Bar where
  getX = barX
  setX r x' = r { barX = x' }

What are you modeling in your code? If we knew more about the problem, we could suggest something less awkward than this object-oriented design shoehorned into a functional language.

3
ответ дан 1 December 2019 в 15:02
поделиться

Если вы создадите экземпляры типов Foldable, вы получите функцию toList, которую можно использовать в качестве основы для вашего средства доступа.

Если Foldable ничего не делает, то, возможно, правильным подходом будет определение интерфейса, который вы хотите, как класс типа и поиск хорошего способа автогенерации производных значений.

Возможно, выполнив

deriving(Data)

, вы могли бы использовать комбинаторы gmap для базирования вашего доступа.

1
ответ дан 1 December 2019 в 15:02
поделиться

Мне кажется, это работа для дженериков. Если бы вы могли пометить свой Int разными новыми типами, тогда вы могли бы написать (с uniplate, модуль PlateData):

data Foo = Foo Something Another deriving (Data,Typeable)
data Bar = Bar Another Thing deriving (Data, Typerable)

data Opts = F Foo | B Bar

newtype Something = S Int
newtype Another = A Int
newtype Thing = T Int

getAnothers opts = [ x | A x <- universeBi opts ]

Это извлечет все чужие из любого места внутри Opts.

Также возможно изменение.

2
ответ дан 1 December 2019 в 15:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: