Для чего используется Представляемый в Haskell?

В вашем коде есть небольшая ошибка. Например, приведенный ниже код работает нормально:

In [107]: import torchvision

# sample input
In [108]: batch_tensor = torch.randn(*(10, 3, 256, 256))

# make grid (2 rows and 5 columns)
In [109]: grid_img = torchvision.utils.make_grid(batch_tensor, nrow=5)

# check shape
In [110]: grid_img.shape
Out[110]: torch.Size([3, 518, 1292])

# reshape and plot
In [111]: plt.imshow(grid_img.permute(1, 2, 0))
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Out[111]: 

, который показывает выход как:

5
задан Alvaro Fuentes 21 January 2019 в 14:42
поделиться

1 ответ

Representable - это функторы типа контейнеров, которые имеют «особые отношения» с другим типом, который служит индексом в Representable. В определении Haskell этот тип индекса задается связанным семейством типов type Rep f :: *

Для каждого значения индекса и для каждого значения значения [113 ], мы можем вызвать функцию index :: f a -> Rep f -> a, чтобы получить соответствующий элемент. И tabulate :: (Rep f -> a) -> f a создает контейнер, в котором каждый элемент получен из своего собственного индекса.

Теперь, вот пример функтора, который НЕ представим: типичный тип списка Haskell []. Можно наивно думать, что он может быть проиндексирован чем-то вроде Natural , но проблема в том, что списки могут быть пустыми или не иметь достаточного количества элементов для достижения заданного индекса.

Всегда бесконечный тип, такой как data Stream a = Stream a (Stream a) - это Representable и он индексируется Natural, потому что всегда будет значение для любого заданного Natural, которое мы передадим в index .

Аналогично, однородная пара data Pair a = Pair a a индексируется по типу Bool: индекс сообщает нам, какой из компонентов выбрать.

Если мы получим зависимую переменную, векторы фиксированного размера будут Representable и проиндексированы конечными натуральными числами , ограниченными размером вектора. Они не индексируются неограниченными Natural сами, потому что тогда у нас может быть доступ за пределы!


Чтение различных экземпляров, определенных для Representable, поучительно, но, похоже, мы имеем перейти к исходному коду, потому что связанные типы не видны в пикше. Некоторые интересные особенности:

  • Функтор Identity индексируется по типу блока (), это имеет смысл, потому что Identity имеет, так сказать, только один «слот», поэтому мы не нужно предоставлять никакой информации.

  • Тип «функции из некоторого типа» ((->) e) индексируется самим типом источника. И index это просто id. Это то, что подразумевается под «изоморфной монаде читателя», потому что монада Reader e является просто новым типом над ((->) e).

  • Composition (вложенность) двух представимых функторов снова Representable, и они индексируются парой исходных индексов! Это имеет смысл: сначала мы должны знать, как индексировать во внешний функтор, а затем во внутренний.

  • Product (спаривание) двух Representable функторов индексируется суммой (Either) исходных индексов. Ветвь Either говорит нам, в какую часть продукта индексировать.

  • Заметное упущение (потому что это не так в общем случае): нет (Representable f, Representable g) => Representable (Sum f g) экземпляра.

0
ответ дан danidiaz 21 January 2019 в 14:42
поделиться
Другие вопросы по тегам:

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