Монады на подсказку? - PullRequest
       5

Монады на подсказку?

10 голосов
/ 11 августа 2011

Можно ли инкрементно взаимодействовать с произвольными экземплярами Monad по приглашению GHCi?

Вы можете вводить команды "do" в интерактивном режиме:

Prelude> x <- return 5

Но, насколько я могу судить,все принудительно вводится в монаду IO ().Что если я вместо этого захочу взаимодействовать с произвольной Монадой?

Я вынужден написать всю последовательность команд внутри гигантского do { ... } и / или напрямую использовать инфиксные операторы?Это нормально, но я бы предпочел «ввести» произвольную монаду и взаимодействовать с ней по очереди.

Возможно?

Ответы [ 2 ]

11 голосов
/ 11 августа 2011

При существующем положении вещей IO -специфичное поведение основывается на том, что IO действия немного похожи на состояние и не могут быть восстановлены. Так что вы можете сказать что-то вроде

s <- readFile "foo.txt"

и получите фактическое значение s :: String.

Совершенно очевидно, что для поддержания такого рода взаимодействия требуется нечто большее, чем просто Monad. Это было бы не так просто с

n <- [1, 2, 3]

, чтобы сказать, что значение n имеет.

Можно, конечно, представить себе адаптацию ghci для открытия подсказки, позволяющей создавать монадические вычисления в стиле do во множественных взаимодействиях командной строки, обеспечивая выполнение всех вычислений при закрытии подсказки. Непонятно, что значит проверять промежуточные значения (кроме генерации коллекций печатных вычислений типа m (IO ()), для активной монады m, конечно).

Но было бы интересно спросить, можно ли выделить и обобщить то, что особенного в IO, которое делает возможным хорошее интерактивное поведение подсказок. Я не могу удержаться от того, чтобы нюхать комонадный рассказ о ценности в контексте о взаимодействии в приглашении, но я еще не отследил его. Можно было бы подумать о том, чтобы обратиться к моему примеру со списком, рассматривая, что будет означать курсор в пространстве возможных значений, в то время как IO имеет курсор, наложенный на него здесь и сейчас реальный мир. Спасибо за пищу для размышлений.

5 голосов
/ 11 августа 2011

Конечно, вы можете.Просто аннотируйте свой тип.
например, для Maybe Monad:

let x = return 5 :: Maybe Int

приведет к

Just 5

Или возьмите монаду списка:

let x = return 5 :: [Int]

приведет к

[5]

Конечно, вы также можете поиграть внутри монады:

let x = return 5 :: Maybe Int
x >>= return . (succ . succ)

, что приведет к Just 7

...