2015-05-08 2 views
0

тип подписи (+), является:Монада типа подписи Пример

(+) :: Num a => a -> a -> a 

Я могу видеть это в:

+ 4 5 

В результате в 9. + 4 принимает и возвращает функцию примерно:

(4 + a) -> a 

... который затем занимает 5 и оценивает по 9. В принципе, две вещи, одна вещь. Я не вижу, как это работает, используя подпись типа оператора привязки. Для меня на практике он всегда выглядит как один, один.

Может кто-нибудь, пожалуйста, проведет меня через простой пример с помощью Модификации Maybe, как я сделал выше для (+)? Надеюсь, это будет вообще полезно для новичков Haskell, подобных мне!

+2

Что вы подразумеваете под этим? Пожалуйста, будьте более конкретными. – AJFarmar

+1

Как пример '(+)' связан с монадами? Оператор monadic bind равен '>> =' и не связан с приложением '(+) 4 9' или частичным приложением' (+) 4'. – chi

+0

@chi Они связаны тем, что и '(+)', и '(>> =)' являются двоичными операторами, но это в значительной степени. – rightfold

ответ

3

Вот тип подписи безвыходном:

(>>=) 
    :: Monad m 
    => m a   -- Left argument 
    -> (a -> m b) -- Right argument 
    -> m b 

Вот пример связывают с двумя аргументами:

Just 1 >>= (\n -> Just (n + 1)) 
^^^^^^  ^^^^^^^^^^^^^^^^^^^^ 
Arg #1  Arg #2 

.. и вычисляет Just 2

+0

О, привет, Габриэль! Я читал ваш сайт/блог. Главным образом над моей головой, но очень интересным, тем не менее. Итак, m a Just 1. Получил это. Затем значение из Just 1 попадает в функцию лямбда. Это значение было бы правильным аргументом, верно? Один добавляется к значению. Как выйдет монада без возврата? О, лямбда до сих пор является аргументом в монаде, так это делает это «автоматически»? – curieux

+2

Для 'Maybe',' return' совпадает с 'Just'. Функция '\ n -> return (n + 1)' делает то же самое, что и функция лямбда в примере Габриэля, но она будет работать для любой монады. – shang

+0

Спасибо всем за тонну очень полезной информации. За последние несколько часов было сделано много вещей. Трудный выбор, но я думаю, что этот ответ наиболее непосредственно ответил на вопрос, и сделал это самым простым способом, и это было то, что мне нужно было понять. – curieux

0

Может ли кто-нибудь пропустить меня через простой пример, используя монаду Maybe так, как я сделал выше для (+)?

(>>=) сочетает монадическое действие с функцией, которая возвращает монадическое действие:

(  >>=   ) :: Maybe Int -> (Int -> Maybe Bool) -> Maybe Bool 
(Just 1 >>=   ) ::    (Int -> Maybe Bool) -> Maybe Bool 
(Just 1 >>= Just . even) ::          Maybe Bool 

Точно так же как с (+), две вещей, которые идут в (монадические действия и функцию, возвращающую монадические действия) и один вещь выходит (монадическое действие).

Для меня на практике он всегда выглядит как один, один из них.

Обратите внимание, что монады Haskell не связаны с монадами APL, которые действительно являются унарными функциями.

0

Дело в том, что путает людей много, когда они видят >>= сигнатуру типа, является то, что она выглядит однобоко

Если вы + вы получите подпись, как это:

(+) :: Num a 
    => a -- 1st arg 
    -> a -- 2nd arg 
    -> a -- return-type 

Если вы принять . вы получите это:

(.) :: (b -> c) -- 1st arg, a function from b to c 
    -> (a -> b) -- 2nd arg, a function from a to b 
    -> a -> c -- return-type, a function from a to c 

пока ничего не страшно

Теперь посмотрим на >>=

(>>=) :: Monad m 
     =>  m a -- 1st arg, a monad a 
     -> (a -> m b) -- 2nd arg, a function from a to a monad b 
     ->  m b -- return-type, a monad b 

1-ый аргумент не соответствует 2-ым, но это нормально, и я собираюсь показать, почему.

Так скажем, у вас есть следующие две функции:

f :: Monad m => a -> m a -- we just need the type signatures 
g :: Monad m => a -> m a 

Затем мы делаем следующее:

\a -> f a >>= \b -> g b 

Что тип f a? это m a, какой тип g b? это m b

Так в основном то, что я сделал это:

function: \a -> f a >>= \b -> g b 
types : a -> m a  b -> m b 

Какой тип аргументов >>= «s? Посмотрите еще раз:

function: \a -> f a >>= \b -> g b 
types : a -> m a  b -> m b 
>>=-args:  m a -> (b -> m b) 

Таким образом, в сущности, что мы сделали здесь, путем добавления лямбда-выражения, мы завершили «отсутствует» тип информации, который сделал подпись «покосившийся»

\n -> (Just n >>= (\m -> Just (m + 1))) -- added extra() for highlighting 

или иначе говоря:

fn a = Just a >>= (\m -> Just (m + 1)) 
fn 3 -- returns Just 4 

по сути, я просто сделал, было создать функцию fn с подписью a -> m a ... Точно так же, как f и g. Итак, что такое >>=, это способ составить монадические функции. Точно так же, как . - это способ составить нормальный функции.

Часы [Don't fear the Monad], которые были источником вдохновения для этого ответа, и в конечном итоге это заставило меня понять, почему он выглядит так, как он.

+0

Спасибо! Это заставит меня попытаться переварить пару, но я вернусь. Спасибо за подключение к (.) - это помогает. На данный момент мне пришло в голову, что аргумент функции всегда является лямбдой в примерах. Это внутри настоящей монады? В этом примере (из LYAHfGG) или общей цепочки, или просто вообще, я думаю, где аргумент функции (a -> m b)? Это похоже на одно значение в одном значении. ghci> return (0,0) >> = landLeft 1 >> = banana >> = landRight 1 Я думаю, что это точка для меня. – curieux

+1

@curieux Это может помочь поместить все круглые скобки в: '(((return (0,0)) >> = (landLeft 1)) >> = banana) >> = (landRight 1)'.'(>> =)' - это просто нормальная функция, которая оказывается инфиксным оператором, в ней нет ничего волшебного. Его первый аргумент находится слева, а второй аргумент - справа. Вы можете сделать синоним без оператора: 'bind xf = x >> = f', а затем вы можете переписать этот пример как« bind (bind (bind (bind (return) (0,0)) (landLeft 1)) banana) (landRight 1) ' –