LINUX.ORG.RU

История изменений

Исправление quasimoto, (текущая версия) :

Сам я пишу на C++ и привык читать инстанцирование класса, как «ConcreteObject - это SomeClass». Как мне показалось, в haskell так делать нельзя.

То что в C++ называется классами и объектами в Haskell называется ADT и значениями (термами).

Например, такой код с классами, объектами и методами:

#include <cstdio>

struct a_t {
    int x, y;
    int sum() { return x + y; }
};

class ab_t {

    // @tagged_union
    enum { a_tag, b_tag } tag;
    union {
        a_t a;
        struct {
            int x, y, z;
            int sum() { return x + y + z; }
        } b;
    } ab_u;

  public:

    ab_t(a_t a_) : tag(a_tag) { ab_u.a = a_; }
    ab_t(int x_, int y_, int z_) : tag(b_tag) { ab_u.b = { x_, y_, z_ }; }

    int sum() { return tag == a_tag ? ab_u.a.sum() : ab_u.b.sum(); }

};

int main()
{
    ab_t ab1({1, 2});
    ab_t ab2(3, 4, 5);
    printf("ab1.sum = %d; ab2.sum = %d\n", ab1.sum(), ab2.sum());
}

В Haskell переводится в код с ADT, значениями и функциями:

import Text.Printf

data A = A Int Int

data AB = A_ A | B Int Int Int

a_ :: Int -> Int -> AB
a_ x y = A_ $ A x y

sumA :: A -> Int
sumA (A x y) = x + y

sumAB :: AB -> Int
sumAB (A_ a) = sumA a
sumAB (B x y z) = x + y + z

main :: IO ()
main = printf "sumAB a = %d; sumAB b = %d\n" (sumAB $ a_ 1 2) (sumAB $ B 3 4 5)

«объект класса» превращается в «терм/значение (алгебраического) типа».

Разница между классами и методами C++ и ADT и функциями Haskell в том, что в C++ может легко начаться наследование, подтипирование и динамическая диспетчеризация, тогда как в Haskell это делается не так легко.

Теперь, если применить в Haskell концепцию классов типов:

class Sum t where
  sumt :: t -> Int

instance Sum A where
  sumt (A x y) = x + y

instance Sum AB where
  sumt (A_ a) = sumt a
  sumt (B x y z) = x + y + z

main :: IO ()
main = printf "sum a = %d; sum b = %d\n" (sumt $ a_ 1 2) (sumt $ B 3 4 5)

то, наоборот, в С++ это уже не так легко. Классы типов не имеют отношения к классам С++, они имеют отношения к интерфейсам и концептам - первые в С++ довольно неудобны:

struct sum_i {
    virtual ~sum_i() {}
    virtual int sum() const = 0;
};

struct a_t : public sum_i {
    int x, y;
    a_t(int x_, int y_) : x(x_), y(y_) {}
    int sum() const { return x + y; }
};

class ab_t : public sum_i {
    // ?
};

а вторых ещё нет (про функторы на них можно посмотреть тут - http://www.pik-potsdam.de/members/lincke/papers/Lincke_et_al_SCP.pdf).

говорит о том что для типа [] определен функтор осуществляющий отображение стрелок над элементами списка в стрелки над списками

[] это и есть функтор - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.103.9637. Класс типов Functor это не функтор и не тип, если мы его интернализируем в язык, это будет класс. То есть если 5 :: Int :: * :: **, тогда Functor :: (* -> *) -> ** (Functor :: (* -> *) -> Constraint в нынешнем GHC, то есть оно там «constraint»).

В зависимости от того, каким функтором является ADT, можно про него сказать разные вещи, в том числе, является ли этот ADT хорошим, то есть не приведёт ли его существование к противоречиям в языке («строго-позитивные функторы»).

А сущность Functor это вещь (класс/constraint) которая нужна либо для того чтобы принять на веру что данный ADT это функтор, объявить функторный интерфейс и реализовать его для данного ADT, либо для того чтобы _доказать_ что данный ADT это функтор (ну и тоже - объявить функторный интерфейс и реализовать его для данного ADT).

«для типа Something инстанцирован/описан/реализован Functor», но не «Something - это Functor»?

Тип Something :: * -> * это функтор (с маленькой буквы и если это ещё функтор, конечно), что подтверждается существованием для этого типа инстанса класса типов (класса) Functor (с большой буквы), если в языке выразимы аксиомы функтора это будет буквальным подтверждением, то есть строгим доказательством того что Something - функтор.

Ну и почему в классе Functor описано отображение для стрелок, но не описано отображение для объектов (как pure из класса Applicative)?

Отображением стрелок/значений/конструкторов/термов/функций/программ занимается стрелка/функция/программа fmap :: (a -> b) -> (f a -> f b) в рантайме, отображением объектов/типов занимается функтор/конструктор типов f :: * -> * во время компиляции. Все Functor, Pointed, Applicative, Monad описывают, на самом деле, только эндофункторы только одной категории Hask - категории всех типов и термов/конструкторов/классов эквивалентности функций-программ (если мы ограничиваемся 1-категорией). Kind * это как раз класс-универсум всех типов, то есть объектов Hask, так что выхлоп GHCi [] :: * -> * на :k [] это, натурально, [] : Hask -> Hask, то есть повод задуматься о том, что конструктор типов [] это эндофунктор на Hask (это нужно доказать основываясь на индуктивном определении []).

Исправление quasimoto, :

Сам я пишу на C++ и привык читать инстанцирование класса, как «ConcreteObject - это SomeClass». Как мне показалось, в haskell так делать нельзя.

То что в C++ называется классами и объектами в Haskell называется ADT и значениями (термами).

Например, такой код с классами, объектами и методами:

#include <cstdio>

struct a_t {
    int x, y;
    int sum() { return x + y; }
};

class ab_t {

    // @tagged_union
    enum { a_tag, b_tag } tag;
    union {
        a_t a;
        struct {
            int x, y, z;
            int sum() { return x + y + z; }
        } b;
    } ab_u;

  public:

    ab_t(a_t a_) : tag(a_tag) { ab_u.a = a_; }
    ab_t(int x_, int y_, int z_) : tag(b_tag) { ab_u.b = { x_, y_, z_ }; }

    int sum() { return tag == a_tag ? ab_u.a.sum() : ab_u.b.sum(); }

};

int main()
{
    ab_t ab1({1, 2});
    ab_t ab2(3, 4, 5);
    printf("ab1.sum = %d; ab2.sum = %d\n", ab1.sum(), ab2.sum());
}

В Haskell переводится в код с ADT, значениями и функциями:

import Text.Printf

data A = A Int Int

data AB = A_ A | B Int Int Int

a_ :: Int -> Int -> AB
a_ x y = A_ $ A x y

sumA :: A -> Int
sumA (A x y) = x + y

sumAB :: AB -> Int
sumAB (A_ a) = sumA a
sumAB (B x y z) = x + y + z

main :: IO ()
main = printf "sumAB a = %d; sumAB b = %d\n" (sumAB $ a_ 1 2) (sumAB $ B 3 4 5)

«объект класса» превращается в «терм/значение (алгебраического) типа».

Разница между классами и методами C++ и ADT и функциями Haskell в том, что в C++ может легко начаться наследование, подтипирование и динамическая диспетчеризация, тогда как в Haskell это делается не так легко.

Теперь, если применить в Haskell концепцию классов типов:

class Sum t where
  sumt :: t -> Int

instance Sum A where
  sumt (A x y) = x + y

instance Sum AB where
  sumt (A_ a) = sumt a
  sumt (B x y z) = x + y + z

main :: IO ()
main = printf "sum a = %d; sum b = %d\n" (sumt $ a_ 1 2) (sumt $ B 3 4 5)

то, наоборот, в С++ это уже не так легко. Классы типов не имеют отношения к классам С++, они имеют отношения к интерфейсам и концептам - первые в С++ довольно неудобны:

struct sum_i {
    virtual ~sum_i() {}
    virtual int sum() const = 0;
};

struct a_t : public sum_i {
    int x, y;
    a_t(int x_, int y_) : x(x_), y(y_) {}
    int sum() const { return x + y; }
};

class ab_t : public sum_i {
    // ?
};

а вторых ещё нет (про функторы на них можно посмотреть тут - http://www.pik-potsdam.de/members/lincke/papers/Lincke_et_al_SCP.pdf).

говорит о том что для типа [] определен функтор осуществляющий отображение стрелок над элементами списка в стрелки над списками

[] это и есть функтор - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.103.9637. Класс типов Functor это не функтор и не тип, если мы его интернализируем в язык, это будет класс. То есть если 5 :: Int :: * :: **, тогда Functor :: (* -> *) -> ** (Functor :: (* -> *) -> Constraint в нынешнем GHC, то есть оно там «constraint»).

В зависимости от того, каким функтором является ADT, можно про него сказать разные вещи, в том числе, является ли этот ADT хорошим, то есть не приведёт ли его существование к противоречиям в языке («строго-позитивные функторы»).

А сущность Functor это вещь (класс/constraint) которая нужна либо для того чтобы принять на веру что данный ADT это функтор, объявить функторный интерфейс и реализовать его для данного ADT, либо для того чтобы _доказать_ что данный ADT это функтор (ну и тоже - объявить функторный интерфейс и реализовать его для данного ADT).

«для типа Something инстанцирован/описан/реализован Functor», но не «Something - это Functor»?

Тип Something :: * -> * это функтор (с маленькой буквы и если это ещё функтор, конечно), что подтверждается существованием для этого типа инстанса класса типов (класса) Functor (с большой буквы), если в языке выразимы аксиомы функтора это будет буквальным подтверждением, то есть строгим доказательством того что Something - функтор.

Ну и почему в классе Functor описано отображение для стрелок, но не описано отображение для объектов (как pure из класса Applicative)?

Отображением стрелок/значений/конструкторов/термов/функций/программ занимается стрелка/функция/программа fmap :: (a -> b) -> ([ a ] -> [ b ]) в рантайме, отображением объектов/типов занимается функтор/конструктор типов [] :: * -> * во время компиляции. Все Functor, Pointed, Applicative, Monad описывают, на самом деле, только эндофункторы только одной категории Hask - категории всех типов и термов/конструкторов/классов эквивалентности функций-программ (если мы ограничиваемся 1-категорией). Kind * это как раз класс-универсум всех типов, то есть объектов Hask, так что выхлоп GHCi [] :: * -> * на :k [] это, натурально, [] : Hask -> Hask, то есть повод задуматься о том, что конструктор типов [] это эндофунктор на Hask (это нужно доказать основываясь на индуктивном определении []).

Исправление quasimoto, :

Сам я пишу на C++ и привык читать инстанцирование класса, как «ConcreteObject - это SomeClass». Как мне показалось, в haskell так делать нельзя.

То что в C++ называется классами и объектами в Haskell называется ADT и значениями (термами).

Например, такой код с классами, объектами и методами:

#include <cstdio>

struct a_t {
    int x, y;
    int sum() { return x + y; }
};

class ab_t {

    // @tagged_union
    enum { a_tag, b_tag } tag;
    union {
        a_t a;
        struct {
            int x, y, z;
            int sum() { return x + y + z; }
        } b;
    } ab_u;

  public:

    ab_t(a_t a_) : tag(a_tag) { ab_u.a = a_; }
    ab_t(int x_, int y_, int z_) : tag(b_tag) { ab_u.b = { x_, y_, z_ }; }

    int sum() { return tag == a_tag ? ab_u.a.sum() : ab_u.b.sum(); }

};

int main()
{
    ab_t ab1({1, 2});
    ab_t ab2(3, 4, 5);
    printf("ab1.sum = %d; ab2.sum = %d\n", ab1.sum(), ab2.sum());
}

В Haskell переводится в код с ADT, значениями и функциями:

import Text.Printf

data A = A Int Int

data AB = A_ A | B Int Int Int

a_ :: Int -> Int -> AB
a_ x y = A_ $ A x y

sumA :: A -> Int
sumA (A x y) = x + y

sumAB :: AB -> Int
sumAB (A_ a) = sumA a
sumAB (B x y z) = x + y + z

main :: IO ()
main = printf "sumAB a = %d; sumAB b = %d\n" (sumAB $ a_ 1 2) (sumAB $ B 3 4 5)

«объект класса» превращается в «терм/значение (алгебраического) типа».

Разница между классами и методами C++ и ADT и функциями Haskell в том, что в C++ может легко начаться наследование, подтипирование и динамическая диспетчеризация, тогда как в Haskell это делается не так легко.

Теперь, если применить в Haskell концепцию классов типов:

class Sum t where
  sumt :: t -> Int

instance Sum A where
  sumt (A x y) = x + y

instance Sum AB where
  sumt (A_ a) = sumt a
  sumt (B x y z) = x + y + z

main :: IO ()
main = printf "sum a = %d; sum b = %d\n" (sumt $ a_ 1 2) (sumt $ B 3 4 5)

то, наоборот, в С++ это уже не так легко. Классы типов не имеют отношения к классам С++, они имеют отношения к интерфейсам и концептам - первые в С++ довольно неудобны:

struct sum_i {
    virtual ~sum_i() {}
    virtual int sum() const = 0;
};

struct a_t : public sum_i {
    int x, y;
    a_t(int x_, int y_) : x(x_), y(y_) {}
    int sum() const { return x + y; }
};

class ab_t : public sum_i {
    // ?
};

а вторых ещё нет (про функторы на них можно посмотреть тут - http://www.pik-potsdam.de/members/lincke/papers/Lincke_et_al_SCP.pdf).

говорит о том что для типа [] определен функтор осуществляющий отображение стрелок над элементами списка в стрелки над списками

[] это и есть функтор - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.103.9637. Класс типов Functor это не функтор и не тип, если мы его интернализируем в язык, это будет класс. То есть если 5 :: Int :: * :: **, тогда Functor :: (* -> *) -> ** (Functor :: (* -> *) -> Constraint в нынешнем GHC).

В зависимости от того, каким функтором является ADT, можно про него сказать разные вещи, в том числе, является ли этот ADT хорошим, то есть не приведёт ли его существование к противоречиям в языке («строго-позитивные функторы»).

А сущность Functor это вещь (класс) которая нужна либо для того чтобы принять на веру что данный ADT это функтор, объявить функторный интерфейс и реализовать его для данного ADT, либо для того чтобы _доказать_ что данный ADT это функтор (ну и тоже - объявить функторный интерфейс и реализовать его для данного ADT).

«для типа Something инстанцирован/описан/реализован Functor», но не «Something - это Functor»?

Тип Something :: * -> * это функтор (с маленькой буквы и если это ещё функтор, конечно), что подтверждается существованием для этого типа инстанса класса типов (класса) Functor (с большой буквы), если в языке выразимы аксиомы функтора это будет буквальным подтверждением, то есть строгим доказательством того что Something - функтор.

Ну и почему в классе Functor описано отображение для стрелок, но не описано отображение для объектов (как pure из класса Applicative)?

Отображением стрелок/значений/конструкторов/термов/функций/программ занимается стрелка/функция/программа fmap :: (a -> b) -> ([ a ] -> [ b ]) в рантайме, отображением объектов/типов занимается функтор/конструктор типов [] :: * -> * во время компиляции. Все Functor, Pointed, Applicative, Monad описывают, на самом деле, только эндофункторы только одной категории Hask - категории всех типов и термов/конструкторов/классов эквивалентности функций-программ (если мы ограничиваемся 1-категорией). Kind * это как раз класс-универсум всех типов, то есть объектов Hask, так что выхлоп GHCi [] :: * -> * на :k [] это, натурально, [] : Hask -> Hask, то есть повод задуматься о том, что конструктор типов [] это эндофунктор на Hask (это нужно доказать основываясь на индуктивном определении []).

Исправление quasimoto, :

Сам я пишу на C++ и привык читать инстанцирование класса, как «ConcreteObject - это SomeClass». Как мне показалось, в haskell так делать нельзя.

То что в C++ называется классами и объектами в Haskell называется ADT и значениями (термами).

Например, такой код с классами, объектами и методами:

#include <cstdio>

struct a_t {
    int x, y;
    int sum() { return x + y; }
};

class ab_t {

    // @tagged_union
    enum { a_tag, b_tag } tag;
    union {
        a_t a;
        struct {
            int x, y, z;
            int sum() { return x + y + z; }
        } b;
    } ab_u;

  public:

    ab_t(a_t a_) : tag(a_tag) { ab_u.a = a_; }
    ab_t(int x_, int y_, int z_) : tag(b_tag) { ab_u.b = { x_, y_, z_ }; }

    int sum() { return tag == a_tag ? ab_u.a.sum() : ab_u.b.sum(); }

};

int main()
{
    ab_t ab1({1, 2});
    ab_t ab2(3, 4, 5);
    printf("ab1.sum = %d; ab2.sum = %d\n", ab1.sum(), ab2.sum());
}

В Haskell переводится в код с ADT, значениями и функциями:

import Text.Printf

data A = A Int Int

data AB = A_ A | B Int Int Int

a_ :: Int -> Int -> AB
a_ x y = A_ $ A x y

sumA :: A -> Int
sumA (A x y) = x + y

sumAB :: AB -> Int
sumAB (A_ a) = sumA a
sumAB (B x y z) = x + y + z

main :: IO ()
main = printf "sumAB a = %d; sumAB b = %d\n" (sumAB $ a_ 1 2) (sumAB $ B 3 4 5)

«объект класса» превращается в «терм/значение (алгебраического) типа».

Разница между классами и методами C++ и ADT и функциями Haskell в том, что в C++ может легко начаться наследование, подтипирование и динамическая диспетчеризация, тогда как в Haskell это делается не так легко.

Теперь, если применить в Haskell концепцию классов типов:

class Sum t where
  sumt :: t -> Int

instance Sum A where
  sumt (A x y) = x + y

instance Sum AB where
  sumt (A_ a) = sumt a
  sumt (B x y z) = x + y + z

main :: IO ()
main = printf "sum a = %d; sum b = %d\n" (sumt $ a_ 1 2) (sumt $ B 3 4 5)

то, наоборот, в С++ это уже не так легко. Классы типов не имеют отношения к классам С++, они имеют отношения к интерфейсам и концептам - первые в С++ довольно неудобны:

struct sum_i {
    virtual ~sum_i() {}
    virtual int sum() const = 0;
};

struct a_t : public sum_i {
    int x, y;
    a_t(int x_, int y_) : x(x_), y(y_) {}
    int sum() const { return x + y; }
};

class ab_t : public sum_i {
    // ?
};

а вторых ещё нет (про функторы на них можно посмотреть тут - http://www.pik-potsdam.de/members/lincke/papers/Lincke_et_al_SCP.pdf).

говорит о том что для типа [] определен функтор осуществляющий отображение стрелок над элементами списка в стрелки над списками

[] это и есть функтор - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.103.9637. Класс типов Functor это не функтор и не тип, если мы его интернализируем в язык, это будет класс. То есть если 5 :: Int :: * :: **, тогда Functor :: * -> **.

В зависимости от того, каким функтором является ADT, можно про него сказать разные вещи, в том числе, является ли этот ADT хорошим, то есть не приведёт ли его существование к противоречиям в языке («строго-позитивные функторы»).

А сущность Functor это вещь (класс) которая нужна либо для того чтобы принять на веру что данный ADT это функтор, объявить функторный интерфейс и реализовать его для данного ADT, либо для того чтобы _доказать_ что данный ADT это функтор (ну и тоже - объявить функторный интерфейс и реализовать его для данного ADT).

«для типа Something инстанцирован/описан/реализован Functor», но не «Something - это Functor»?

Тип Something :: * -> * это функтор (с маленькой буквы и если это ещё функтор, конечно), что подтверждается существованием для этого типа инстанса класса типов (класса) Functor (с большой буквы), если в языке выразимы аксиомы функтора это будет буквальным подтверждением, то есть строгим доказательством того что Something - функтор.

Ну и почему в классе Functor описано отображение для стрелок, но не описано отображение для объектов (как pure из класса Applicative)?

Отображением стрелок/значений/конструкторов/термов/функций/программ занимается стрелка/функция/программа fmap :: (a -> b) -> ([ a ] -> [ b ]) в рантайме, отображением объектов/типов занимается функтор/конструктор типов [] :: * -> * во время компиляции. Все Functor, Pointed, Applicative, Monad описывают, на самом деле, только эндофункторы только одной категории Hask - категории всех типов и термов/конструкторов/классов эквивалентности функций-программ (если мы ограничиваемся 1-категорией). Kind * это как раз класс-универсум всех типов, то есть объектов Hask, так что выхлоп GHCi [] :: * -> * на :k [] это, натурально, [] : Hask -> Hask, то есть повод задуматься о том, что конструктор типов [] это эндофунктор на Hask (это нужно доказать основываясь на индуктивном определении []).

Исходная версия quasimoto, :

Сам я пишу на C++ и привык читать инстанцирование класса, как «ConcreteObject - это SomeClass». Как мне показалось, в haskell так делать нельзя.

То что в C++ называется классами и объектами в Haskell называется ADT и значениями (термами).

Например, такой код с классами, объектами и методами:

#include <cstdio>

struct a_t {
    int x, y;
    int sum() { return x + y; }
};

class ab_t {

    // @tagged_union
    enum { a_tag, b_tag } tag;
    union {
        a_t a;
        struct {
            int x, y, z;
            int sum() { return x + y + z; }
        } b;
    } ab_u;

  public:

    ab_t(a_t a_) : tag(a_tag) { ab_u.a = a_; }
    ab_t(int x_, int y_, int z_) : tag(b_tag) { ab_u.b = { x_, y_, z_ }; }

    int sum() { return tag == a_tag ? ab_u.a.sum() : ab_u.b.sum(); }

};

int main()
{
    ab_t ab1({1, 2});
    ab_t ab2(3, 4, 5);
    printf("ab1.sum = %d; ab2.sum = %d\n", ab1.sum(), ab2.sum());
}

В Haskell переводится в код с ADT, значениями и функциями:

import Text.Printf

data A = A Int Int

data AB = A_ A | B Int Int Int

a_ :: Int -> Int -> AB
a_ x y = A_ $ A x y

sumA :: A -> Int
sumA (A x y) = x + y

sumAB :: AB -> Int
sumAB (A_ a) = sumA a
sumAB (B x y z) = x + y + z

main :: IO ()
main = printf "sumAB a = %d; sumAB b = %d\n" (sumAB $ a_ 1 2) (sumAB $ B 3 4 5)

«объект класса» превращается в «терм/значение (алгебраического) типа».

Разница между классами и методами C++ и ADT и функциями Haskell в том, что в C++ может легко начаться наследование, подтипирование и динамическая диспетчеризация, тогда как в Haskell это делается не так легко.

Теперь, если применить в Haskell концепцию классов типов:

class Sum t where
  sumt :: t -> Int

instance Sum A where
  sumt (A x y) = x + y

instance Sum AB where
  sumt (A_ a) = sumt a
  sumt (B x y z) = x + y + z

main :: IO ()
main = printf "sum a = %d; sum b = %d\n" (sumt $ a_ 1 2) (sumt $ B 3 4 5)

то, наоборот, в С++ это уже не так легко. Классы типов не имеют отношения к классам С++, они имеют отношения к интерфейсам и концептам - первые в С++ довольно неудобны:

struct sum_i {
    virtual ~sum_i() {}
    virtual int sum() const = 0;
};

struct a_t : public sum_i {
    int x, y;
    a_t(int x_, int y_) : x(x_), y(y_) {}
    int sum() const { return x + y; }
};

class ab_t : public sum_i {
    // ?
};

а вторых ещё нет (про функторы на них можно посмотреть тут - http://www.pik-potsdam.de/members/lincke/papers/Lincke_et_al_SCP.pdf).

говорит о том что для типа [] определен функтор осуществляющий отображение стрелок над элементами списка в стрелки над списками

[] это и есть функтор - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.103.9637. Класс типов Functor это не функтор и не тип, если мы его интернализируем в язык, это будет класс. То есть если 5 :: Int :: * :: **, тогда Functor :: * -> **.

В зависимости от того, каким функтором является ADT, можно про него сказать разные вещи, в том числе, является ли этот ADT хорошим, то есть не приведёт ли его существование к противоречиям в языке («строго-позитивные функторы»).

А сущность Functor это вещь (класс) которая нужна либо для того чтобы принять на веру что данный ADT это функтор, объявить функторный интерфейс и реализовать его для данного ADT, либо для того чтобы _доказать_ что данный ADT это функтор (ну и тоже - объявить функторный интерфейс и реализовать его для данного ADT).

«для типа Something инстанцирован/описан/реализован Functor», но не «Something - это Functor»?

Тип Something :: * -> * это функтор (с маленькой буквы и если это ещё функтор, конечно), что подтверждается существованием для этого типа инстанса класса типов (класса) Functor (с большой буквы), если в языке выразимы аксиомы функтора это будет буквальным подтверждением, то есть строгим доказательством того что Something - функтор.

Ну и почему в классе Functor описано отображение для стрелок, но не описано отображение для объектов (как pure из класса Applicative)?

Отображением стрелок/значений/конструкторов/термов/функций/программ занимается стрелка/функция/программа fmap :: (a -> b) -> ([a] -> ) в рантайме, отображением объектов/типов занимается функтор/конструктор типов [] :: * -> * во время компиляции. Все Functor, Pointed, Applicative, Monad описывают, на самом деле, только эндофункторы только одной категории Hask - категории всех типов и термов/конструкторов/классов эквивалентности функций-программ (если мы ограничиваемся 1-категорией). Kind * это как раз класс-универсум всех типов, то есть объектов Hask, так что выхлоп GHCi [] :: * -> * на :k [] это, натурально, [] : Hask -> Hask, то есть повод задуматься о том, что конструктор типов [] это эндофунктор на Hask (это нужно доказать основываясь на индуктивном определении []).