2010-06-03 3 views
3

В Monads for natural language semantics Chung-Chieh Shan показывает, как монады могут использоваться, чтобы дать однозначное единообразное повторение стандартных учетных записей некоторых видов естественных языковых явлений (опрос, фокус, интенсиональность и количественное определение). Он определяет две композиции, A_M и A'_M, которые полезны для этой цели.Необычная подпись типа

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

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

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

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

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

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

Ничего полезного не появляется в Hoogle для m (m a -> b) -> m a -> m b или m (a -> b) -> a -> m b.

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

+1

'вещь f = ap f. return' – yairchu

+0

Я немного смутился, потому что на самом деле я написал несвязанный комбинатор '()' 'как' liftA2 (\ b t e -> if b then t else e) '. –

ответ

6

Часть причины, по которой это выглядит странно, может быть частью (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 w) => w a -> (w a -> b) -> w b 
+0

Ах, версия-функтор очень понятна: D –

+0

Это обобщение флип (для (r->) функтора). – sdcvvc

+0

Это '(??)' от объектива. ['xs ?? x = fmap ($ x) xs'] (https://hackage.haskell.org/package/lens-4.15.1/docs/Control-Lens-Lens.html#v:-63--63-) –

4

Только играя в 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

Это напоминает мне о loeb function:

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

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

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

+0

Да это 'loeb f = fix (f ??)'? –

Смежные вопросы