Scalaz Bind[Seq] класс типов

В настоящее время я портирую код из традиционного Scala в стиль Scalaz.

В большинстве моего кода довольно часто используется черта Seq в моих открытых сигнатурах API, а не конкретный тип (например, List, Vector) напрямую. Однако это создает некоторые проблемы со Scalaz, так как он не обеспечивает реализацию класса типов Bind[Seq].

т.е. это будет работать правильно.

List(1,2,3,4) >>= bindOperation

Но это не будет

Seq(1,2,3,4) >>= bindOperation

с ошибкой could not find implicit value for parameter F0: scalaz.Bind[Seq]

Я предполагаю, что это преднамеренное проектное решение в Scalaz - однако я не уверен относительно предполагаемой / лучшей практики относительно того, как предшествовать.

Должен ли я вместо этого писать свой код непосредственно в List/Vector, а не использовать более гибкий интерфейс Seq? Или я должен просто определить свой собственный класс типов Bind[Seq]?

1 ответ

Решение

Библиотека коллекций делает сальто для размещения подтипов: когда вы используете map для определенного типа коллекции (список, карта и т. д.) вы (обычно) получите тот же тип обратно. Он управляет этим путем использования чрезвычайно сложной иерархии наследования вместе с классами типов, такими как CanBuildFrom, Это делает работу (по крайней мере, возможно), но сложность не кажется очень принципиальной. Это беспорядок. Многие люди ненавидят это.

Сложность, как правило, довольно проста для пользователя библиотеки, но для разработчика библиотеки это кошмар. Если я предоставлю экземпляр монады для Seq, это означает, что все типы моих пользователей увеличены в иерархии Seq каждый тип они используют монадическую операцию.

Людям Скалаза, как правило, не очень нравится подтипирование, так что по большей части Скалаз остается вокруг листьев иерархии.List, Vectorи т. д. Вы можете увидеть некоторые обсуждения этого решения, например, в списке рассылки.

Когда я впервые начал использовать Scalaz, я написал много служебного кода, который пытался предоставить экземпляры для Seqи т. д. и сделать их пригодными для использования с CanBuildFrom, Тогда я остановился, и теперь я склонен следовать Скалазу только когда-либо используя List, Vector, Map, а также Set в моем собственном коде. Если вы привержены "Scalaz style", вы должны сделать то же самое (или даже принять собственный Scalaz) IList, ISet, ==>>, так далее.). Тем не менее, вы не найдете четкого соглашения о передовых методах в более общем плане, и оба подхода можно использовать для работы, поэтому вам просто нужно поэкспериментировать, чтобы найти тот, который вы предпочитаете.

Другие вопросы по тегам