в Haskell, как мне вывести: Категория экземпляра (Moore a b -> Moore b c)

Я пытаюсь получить экземпляр категории для трансформаторов автомата Мура, где:

data Moore a b = Moore b (a -> Moore a b)
type MooreT a b c = (Moore a b -> Moore a c)

Проблема в том, что MooreT имеет 3 параметра, а Category всего 2. Пробовал писать: instance Category (MooreT a), но не получилось.

Дело в том, что параметр a на самом деле не имеет значения для определения id и (.). Например:

id :: MooreT a b b
id x = x

Есть ли способ определить такой экземпляр? Или мне нужно определить MooreT для определенного типа a, например type IntMooreT a b = MooreT Int a b?

Я все еще новичок в Haskell, поэтому извините, если это глупый вопрос.


person Reddog    schedule 22.09.2016    source источник
comment
Я пытался написать: instance Category (MooreT a), но у меня не получилось. Это правильный способ сделать это. Укажите фактический код, который вы пробовали, и сообщение об ошибке, с которым вы столкнулись, и мы можем помочь вам исправить это.   -  person Benjamin Hodgson♦    schedule 22.09.2016
comment
Вот ошибка: * Синоним типа MooreT' should have 3 arguments, but has been given 1 * In the instance declaration for Category (MooreT a)'   -  person Reddog    schedule 22.09.2016
comment
@Reddog Компилятор точно сказал вам, в чем проблема (вы должны прочитать ошибки, которые он вам дает) - MooreT - это синоним типа, что означает, что он должен полностью применяться при использовании (т. Е. Он должен применяться к 3 аргументам) и в instance Category (MooreT a) явно применяется только к одному.   -  person user2407038    schedule 22.09.2016
comment
@user2407038 user2407038 Что ж, если бы он был полностью применен, в нем отсутствовали бы два свободных параметра, которые должны быть экземпляром Category. Я ответил Бенджамину Ходжсону, поскольку он заявил: «Это правильный способ сделать это». Я действительно читаю ошибки GHCI.   -  person Reddog    schedule 22.09.2016
comment
@Reddog Именно поэтому вы обычно не можете создавать синонимы типов в экземплярах классов типов - вы должны обернуть тип в newtype или data.   -  person user2407038    schedule 22.09.2016


Ответы (1)


MooreT a является синонимом type для подтипа (->). У (->) уже есть экземпляр Category, поэтому у MooreT a тоже есть.

ghci может проверить, сочиняют ли уже MooreT файлы с .. Начните с ваших определений и импорта для Category, проверив правильность импорта .

Prelude> data Moore a b = Moore b (a -> Moore a b)
Prelude> type MooreT a b c = (Moore a b -> Moore a c)
Prelude> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
Prelude> import Control.Category
Prelude Control.Category> import Prelude hiding ((.), id)
Control.Category Prelude> :t (.)
(.) :: Category cat => cat b c -> cat a b -> cat a c

Сделайте пару фиктивных значений MooreT, f и g

Control.Category Prelude> data A = A
Control.Category Prelude> data B = B
Control.Category Prelude> data C = C
Control.Category Prelude> data D = D
Control.Category Prelude> f = undefined :: MooreT A B C
Control.Category Prelude> :t f
f :: MooreT A B C
Control.Category Prelude> g = undefined :: MooreT A C D

Проверить, что композиция работает

Control.Category Prelude> :t g . f
g . f :: Moore A B -> Moore A D
person Cirdec    schedule 22.09.2016
comment
Конечно ты прав! За деревьями леса не видно :) Все же интересно, почему instance Category (MooreT a) where ... выдает ошибку. - person Reddog; 22.09.2016