2014-10-14 6 views
3

Я работаю над некоторыми вводными материалами Haskell и в настоящее время переживаю Монады. Я концептуально понимаю, что оператор >>= имеет тип:Haskell: Смутно о типе `>> =` operator

(Monad m) => m a -> (a -> m b) -> m b.

В этом контексте, я запутался, почему следующий код работает, то есть, почему она не приводит к несоответствию типа:

main = getLine >>= \xs -> putStrLn xs 

Поскольку мы знаем, что getLine :: IO String, я бы предположить, что он может быть «связан» с функцией типа String -> IO String. Однако putStrLn имеет другой тип: putStrLn :: String -> IO().

Так почему же Haskell позволяет нам использовать >>= с этими двумя функциями?

+5

'a' является' String', 'm' является' IO' и 'b' is'() '(единица или пустой кортеж). Таким образом, тип лямбда - 'String -> IO()' – Mephy

ответ

14

Давайте просто выстраиваться типы:

(>>=) :: m  a -> ( a -> m b) -> m b 
getLine :: IO String 
putStrLn ::    (String -> IO()) 

Здесь мы имеем m = IO, a = String и b =(), поэтому мы могут заменить их на подпись типа >>=, чтобы получить окончательную подпись типа

(>>=) :: IO String -> (String -> IO()) -> IO() 
5

() действительный тип (называемый единицей, обратите внимание, что он содержит только одно возможное не нижнее значение), а в определении будет b.

a = String и b = (), таким образом, мы получаем:

IO String -> (String -> IO()) -> IO()

+1

(Он содержит два значения, другой - нижний.;) –

4

Поскольку мы знаем, что getLine :: IO String, я бы предположить, что это может быть «связаны» с функцией типа String -> IO String.

Почему вы так думаете? Посмотрите еще раз на тип подписи:

(>>=) :: m a -> (a -> m b) -> m b 

Вещь в слева m a, вещь по праву является m b. В частности, бит в середине, a -> m b, говорит, что функция, которую вы переходите на >>=, принимает a и возвращает m b. Он не говорит, что он должен вернуть m a, он говорит, что это может быть m b, где b - любой случайный тип. Он не должен соответствовать a.

В вашем примере функция лямбда принимает String и возвращает IO(). Таким образом, a = String и b =(). И это нормально.