0

Как это сделать в чистом виде?Как читать из stdin?

псевдокод:

loop: 
    input = read_stdin 
    if input == "q": 
     break loop 
    else: 
     print "you input: ", input 

На самом деле, я имел взгляд на каком-то PDF. Но у меня появилось воображение. Трудно иметь дело с stdin и stdout. Могу ли я использовать пример кода для использования stdio?

Следуя инструкциям Keelan, я закончил свою небольшую программу.

module std_in_out_loop 
import StdEnv 

loop :: *File -> *File 
loop io 
# io = fwrites "input your name: " io 
# (name, io) = freadline io 
# name = name % (0, size name - 2) 
| name == "q" 
# io = fwrites "Bye!\n" io 
= io 
| name == "" 
# io = fwrites "What's your name?\n" io 
= loop io 
| otherwise 
# io = fwrites ("hello " +++ name +++ "\n") io 
= loop io 

Start:: *World -> *World 
Start world 
# (io, world) = stdio world 
# io = loop io 
# (ok, world) = fclose io world 
| not ok = abort "Cannot close io.\n" 
| otherwise = world 
+0

Почему вы не используете Google, чтобы найти учебник и сделать это самостоятельно? –

+0

Я не могу этого найти. вы можете дать мне ссылку? Пожалуйста. Благодарю. –

+0

[one google search away] (http://www.inf.ufsc.br/~jbosco/cleanBookI.pdf) –

ответ

0

С Clean 2.2 manual, глава 9:

Although Clean is purely functional, operations with side-effects (I/O operations, for instance) are permitted. To achieve this without violating the semantics, the classical types are supplied with so called uniqueness attributes. If an argument of a function is indicated as unique, it is guaranteed that at run-time the corresponding actual object is local, i.e. there are no other references to it. Clearly, a destructive update of such a “unique object” can be performed safely.

В частности, вы можете сделать Start, который обычно имеет Арность 0 (не принимает никаких аргументов), функцию от *World к *World. Идея состоит в том, что теперь у нас есть функция, которая меняет мир, а это означает, что допустимы побочные эффекты (они больше не являются побочными эффектами, а являются операциями в мире).

* указывает уникальностьWorld. Это означает, что вы никогда не можете иметь два экземпляра мирового аргумента. Например, следующий будет дать время компиляции уникальность ошибки:

Start :: *World -> *(*World, *World) 
Start w = (w, w) 

Для использования стандартного ввода-вывода, вам необходимы функции из модуля StdFile в StdEnv. Функции, которые вы собираетесь нужны:

stdio :: !*World -> *(!*File, !*World) 
fclose :: !*File !*World -> !(!Bool, !*World) 

Я упрощена типам немного, на самом деле они из класса FileSystem. stdio открывает уникальныйFile из мира, а также возвращает новый, измененный мир. fclose закрывает файл в мире и возвращает флаг успеха и измененный мир.

Затем, чтобы читать и писать из этого STDIO файла, вы можете использовать:

freadline :: !*File -> *(!*String, !*File) 
fwrites :: !String !*File -> !*File 

freadline читает строку в строку, включая символ новой строки. fwrites записывает строку в файл, обычно вы хотите включить символ новой строки при записи в stdio.

Собираем вместе:

Start :: *World -> *World 
Start w 
# (io,w) = stdio w        // open stdio 
# io = fwrites "What is your name?\n" io   // ask for name 
# (name,io) = freadline io      // read in name 
# name = name % (0, size name - 2)    // remove \n from name 
# io = fwrites ("Hello, " +++ name +++ "!\n") io // greet user 
# (ok,w) = fclose io w       // close stdio 
| not ok = abort "Couldn't close stdio"   // abort in case of failure 
= w            // return world from Start 

Синтаксис # может быть новым для вас. Это своего рода let, который позволяет использовать такое же имя для файлов (или других вещей), что более удобно, чем при использовании, например:

Start w = w3 
where 
    (io, w1) = stdio w 
    io1 = fwrites "What is your name?\n" io 
    (name, io2) = freadline io1 
    //... 
    (ok, w3) = fclose io10 w2 

Теперь вы должны быть в состоянии делать то, что вы хотите в псевдокоде, используя вспомогательная функция loop :: *File -> *File, которая называет себя рекурсивно до ввода q.

Есть больше функций, чем только freadline и fwrites, см. StdFile.dcl за идею.

+0

Привет, Камиль, Рад видеть тебя снова. Вы не возражаете? дать мне icl-файл? что эквивалентно псевдокоду. Позвольте мне поиграть с ним? И тогда я вернусь, чтобы прочитать ваши инструкции. Это может быть глупо? Я не знаю? Пожалуйста. Благодаря! –

+0

@sama вещь после «Объединение» - это готовый пример, просто добавьте заголовок модуля и «импортируйте StdEnv». Попробуйте написать 'loop :: * File -> * File' самостоятельно, как я предложил в последнем абзаце. Если вы не справитесь, задайте новый вопрос, включая ваш код и конкретный вопрос. Благодаря! – Keelan

+0

Привет, Камил! Еще раз спасибо. Для меня? CLEAN очень отличается, ** Start ** - единственный шанс выпустить что-то? (другой язык может делать это везде. Например, для python? Если Yoy хочет что-то прочитать или вывести что-то, это очень просто. Я могу сделать это, и написать код для себя). Но для меня это сложно. Извините, я понятия не имею, чтобы сгруппировать их в файл icl. –

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