Но я все же хотел бы выяснить, почему не работает первая версия.Например, чем отличается класс типов Functor, например, от полугруппы, где первая версия работала просто отлично.
Давайте рассмотрим определение класса Functor
:
class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
Itсодержит f a
и f b
типов в сигнатуре типа map
, которая ясно указывает, что f
имеет тип Type -> Type
(он "несет" другой тип).С другой стороны, Semigroup
явно относится к простым типам типа Type
:
class Semigroup a where
append :: a -> a -> a
Итак, Semigroup
- это класс, который можно определить для простых типов, таких как String
, Int
,List a
, Map k v
или даже функция a -> b
(которая также может быть записана как (->) a b
), но не конструкторы типов, для которых требуется другой тип, например List
Map k
(->) a
(я должен использовать эту записьздесь).
С другой стороны, классу Functor
требуются конструкторы типов, поэтому вы можете иметь такие экземпляры, как Functor List
, Functor (Map k)
или Functor ((->) a)
.