В свободное время я изучаю Haskell, так что это вопрос для начинающих.
] В своих чтениях я наткнулся на пример, иллюстрирующий, как Либо
становится экземпляром Functor
:
instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
Теперь я пытаюсь понять, почему реализация отображается в случае конструктора значения Right
, но не в случае Left
?
Вот мое понимание:
Сначала позвольте мне переписать приведенный выше экземпляр как
instance Functor (Either a) where
fmap g (Right x) = Right (g x)
fmap g (Left x) = Left x
Теперь:
Я знаю, что fmap :: (c -> d) -> fc -> fd
, если мы заменим f
на Либо a
, мы получим fmap :: (c -> d) -> Либо ac -> Либо ad
тип of Right (gx)
равно Либо a (gx)
, а тип gx
- d
, поэтому мы имеем, что тип of Right (gx)
is Either ad
, чего мы и ожидаем от fmap
(см. 2. выше)
, если мы посмотрим на Left (gx)
, мы можем использовать те же рассуждения, чтобы сказать, что его тип Либо (gx) b
, то есть Либо db
, что не то, что мы ожидаем из fmap
(см. 2. выше): d
должен быть вторым параметром, а не первым! Поэтому мы не можем сопоставить Left
.
public: class Message {/*...*/}; typedef int (* Обратный вызов) (Сообщение * msg); void registerCallback (int msgclass, Callback f);
} ...
РЕДАКТИРОВАТЬ: МОТИВАЦИЯ
Предположим, я определяю класс обработчика как
class Handler {
public:
class Message { /*...*/ };
typedef int (*Callback)(Message *msg);
void registerCallback(int msgclass, Callback f);
};
Клиент может выполнять
int f1(Handler::Message *msg)
{ /* handle message */ }
int f2(Handler::Message *msg)
{ /* handle message */ }
int main(){
Handler h;
h.registerCallback(1, f1);
h.registerCallback(2, f2);
// ....
}
Компилятор действительно проверяет, что f1
и f2
подходят в качестве параметров для registerCallback
, однако клиент должен правильно определить f1
и f2
. Поскольку у меня уже есть typedef
ed Callback
, я бы хотел, чтобы клиент мог использовать его вместо этого.
END EDIT
Я бы хотел что-то сделать примерно так:
typedef int arithmetic(int i, int j);
arithmetic sum
{
return i+j;
}
arithmetic max
{
return (i>j)? i:j;
}
// etc.
Однако оба
arithmetic sum
arithmetic sum()
не компилируются, а также этот
arithmetic sum(int i, int j)
, который дает ошибку компилятора
func.cpp: 4: error: 'sum' объявлено как функция, возвращающая функцию
Причина, по которой я хочу это, заключается в том, что я хочу иметь класс Handler
, который предоставил бы typedef
для функции обратного вызова, которую он принимает, включая список параметров .