Подпись необычного типа - PullRequest
3 голосов
/ 03 июня 2010

In Монады для семантики естественного языка , Chung-Chieh Shan показывает, как монады могут быть использованы, чтобы дать хорошо единообразное повторение стандартных описаний некоторых различных типов явлений естественного языка (вопросительные, фокусирующие, интенциональность) и количественное определение). Он определяет две операции композиции, A_M и A'_M, которые полезны для этой цели.

Первый просто ap. В монете powerset ap есть недетерминированная функция приложения, которая полезна для обработки семантики вопросительных знаков; в монаде читателя это соответствует обычному анализу экстенсиональной композиции; и т.д.

Это имеет смысл. Вторичная операция компоновки, однако, имеет сигнатуру типа, которая мне просто кажется странной:

(<?>) :: (Monad m) => m (m a -> b) -> m a -> m b

(Шан называет это A'_M, но я назову здесь <?>.) Определение - это то, что вы ожидаете от типов; это очень близко соответствует ap:

g <?> x = g >>= \h -> return $ h x

Мне кажется, я могу понять, как это делает то, что предполагается в контексте статьи (обрабатывать вопросительные глаголы для вопросительных слов, выполнять интенциональные композиции и т. Д.) То, что он делает, не очень сложно, но немного странно видеть, что он играет здесь такую ​​важную роль, поскольку это не та идиома, которую я видел в Haskell раньше.

Ничего полезного в Google не приходит ни для m (m a -> b) -> m a -> m b, ни для m (a -> b) -> a -> m b.

Это выглядит знакомо кому-либо из других контекстов? Вы когда-нибудь писали эту функцию?

Ответы [ 3 ]

6 голосов
/ 03 июня 2010

Частично причина, по которой это выглядит странно, может быть частью (m a -> b) - на самом деле это ограничение наиболее полиморфного типа, выведенного для данной реализации, и вырванное из контекста, для монады бессмысленно. Самый общий тип выглядит так:

> :t (\g x -> g >>= \h -> return $ h x)
(\g x -> g >>= \h -> return $ h x) :: (Monad m) => m (t -> a) -> t -> m a

Более общая версия может быть написана без использования монад:

a'_F :: (Functor f) => f (a -> b) -> a -> f b
a'_F g x = fmap ($ x) g

В данном случае это не имеет отношения к делу, но тип, подобный f a -> b, действительно напоминает второй аргумент операции cobind над comonad:

(=>>) :: (Comonad w) => w a -> (w a -> b) -> w b
4 голосов
/ 03 июня 2010

Просто играя в ghci, я попробовал следующее:

> [length, sum, maximum, minimum, const 666] <?> [1, 2, 3]
[3, 6, 3, 1, 666]

> Nothing <?> Nothing
Nothing
> Just (maybe 0 (^2)) <?> Just 7
49
> Just (maybe 0 (^2)) <?> Nothing
0

> :m + Control.Monad.Instances

> (((+2) >>=) <?> 3) (^) -- (3+2)^3
125
> (((+2) .) <?> 3) (^4) -- (3^4)+2
83
> ((. (+2)) <?> 3) (^4) -- (3+2)^4
625

Я думаю, что на самом деле написал список конкретной версии этого. Из всех этих примеров я считаю версию списка наиболее понятной для общего случая.

1 голос
/ 12 июня 2010

Это напоминает мне о функции loeb :

> loeb :: Functor a => a (a x -> x) -> a x
> loeb x = fmap (\a -> a (loeb x)) x

loeb узлы связи. Это означает, что если a является каким-то контейнером, loeb создает контейнер из контейнера правил, в которых указано, как сделать каждый элемент из конечного результата.

<?> аналогичен, но вместо применения правил к своему собственному конечному результату он применяет правила к другому контейнеру, поэтому он больше не является круглым.

...