Развернуть значение из операции ввода-вывода позже

Здравствуйте, мне было интересно, как вы можете развернуть значение позже в монаде IO? Если a<-expression связывает результат с a, то нельзя ли использовать (<-expression) в качестве параметра для данного метода, например: method (<-expression) где метод method принимает результат оценки?

Код

let inh=openFile "myfile" WriteMode
let outh=openFile "out.txt" WriteMode 
hPutStrLn (<-outh) ((<-inh)>>=getLine)

Я не вошел в главу Monad, только основные блоки <- и do, но я полагаю, что это связано с монадами. Затем, если я хочу передать result, если оценка hGetLine не может быть, я использую что-то вроде:

(<-expression)=>>hGetLine

person Bercovici Adrian    schedule 24.07.2018    source источник
comment
<- это не функция, это часть синтаксиса. Это синтаксический сахар для вызовов (>>=). Вот почему вы не можете использовать его таким образом. Если вы еще не хотите использовать эти Monad методы напрямую, как насчет inh <- openFile ...; outh <- openFile ...; r <- hGetLine inh; hPutStrLn outh r вместо let?   -  person David Young    schedule 24.07.2018
comment
Хорошо, variable<-expression нельзя использовать без левого аргумента. Так что я должен войти в главу monad. Так что я могу использовать это так? hPutStrLn (=<<inh) ((=<<outh)>>=hGetLine.   -  person Bercovici Adrian    schedule 24.07.2018
comment
да, это часть do-нотации. начните с нотации do.   -  person Will Ness    schedule 24.07.2018
comment
Было предложение InlineDoBind, которое похоже на то, что вы думаете.   -  person freestyle    schedule 24.07.2018
comment
<- и do по определению относятся к монадам (без учета расширения ApplicativeDo). Я мягко предлагаю прочитать вашу главу о монадах.   -  person chepner    schedule 24.07.2018
comment
@freestyle: который я на самом деле отправил как InlineBindings, но моя работа над этим выдохлась; Я надеюсь, что когда-нибудь еще до него доберусь.   -  person Jon Purdy    schedule 26.07.2018


Ответы (1)


Вы уже понимаете, что оператор <- как бы разворачивает значение IO, но на самом деле это синтаксис нотации do и может быть выражен следующим образом (на самом деле я не уверен, каких результатов вы пытаетесь достичь, но следующий пример просто читает содержимое из одного файла и помещает содержимое в другой файл):

import System.IO

main = do
  inh <- openFile "myfile" ReadMode
  outh <- openFile "out.txt" WriteMode
  inContent <- hGetLine inh
  hPutStrLn outh inContent
  hClose outh

Согласно документации hGetLine, hPutStrlLn и hClose принимать значения типа Handle в качестве аргумента, но openFile возвращает IO Handle, поэтому нам нужно развернуть его с помощью оператора <-

Но если вы хотите вместо этого использовать функцию >>=, то это один из вариантов сделать это:

import System.IO

writeContentOfMyFile :: Handle -> IO ()
writeContentOfMyFile handler =
  openFile "myfile" ReadMode >>= hGetLine >>= hPutStrLn handler

main =
  withFile "out.txt" WriteMode writeContentOfMyFile
person Igor Drozdov    schedule 24.07.2018
comment
Но чего я не понимаю, так это когда вы используете =<< и когда >>= - person Bercovici Adrian; 24.07.2018
comment
это в основном то же самое, единственная разница заключается в порядке аргументов. Например, у вас есть line типа IO String и вы хотите его распечатать. Вы можете сделать это либо через print =<< a, либо через a >>= print - person Igor Drozdov; 24.07.2018