2016-04-17 3 views
0
newtype ReaderT r m a :: * -> (* -> *) -> * -> * 

Я не могу понять, как понять выше выражения, особенно * -> (* -> *) -> * -> *Считыватель Трансформатор Монада

+0

Ваш вопрос и пример не так понятны –

+0

это вид-подпись - символ '*' обозначает тип, поэтому он сообщает вам, что 'r' - это тип,' m' - это тип-конструктор (например, '' Может быть, 'или' IO' - вы даете им тип, и они возвращают один), а 'a' является типом - результат (который является« ReaderT rma') снова является типом - он просто поможет вам понять вовлеченные части ;) – Carsten

ответ

4

Это должно быть на самом деле

ReaderT :: * -> (* -> *) -> * -> * 

Грубо говоря, выше тип является типом функции, принимает аргумент типа *, другой тип * -> *, другой тип * и производит результат типа *. Тип * является «типом всех типов». Например. Int :: *, Char :: * и т.д.

Чтобы избежать путаницы, * не действительно называется «тип», но «своего рода», чтобы отразить, что он работает на более высоком уровне. Например, 'a' имеет тип Char, а Char имеет вид *.

Наконец, вид * -> * является своего рода конструкторами одинарных типа, такие как Maybe, [], IO, (,) Char, Either Bool и т.д. Все это принять аргумент типа и возвращать тип. Вид * -> * также является видом любого функтора, аппликативного или монада.

Так что, если у нас есть тип r, конструктор типа m (обычно, монада), и тип a, мы имеем:

r :: * 
m :: (* -> *) 
a :: * 
ReaderT :: * -> (* -> *) -> * -> * 
ReaderT r :: (* -> *) -> * -> * 
ReaderT r m :: * -> * 
ReaderT r m a :: * 

Следовательно, когда пройдены все три аргумента, результат ReaderT r m a является типом.

+0

why '(* -> *)' является монадой? – Gilgamesz

+2

@Gilgamesz '* -> *' не является монадой, но если у вас есть монада 'm', то' m' должен иметь вид '* -> *'. Например. 'm = Maybe', или' m = IO' – chi

+0

'(,)' is '* -> * -> *' no? Я думал, что вы не можете думать о '* -> *' как '*'. – jakubdaniel