How to do this in Clean?
Pseudo code:
loop:
input = read_stdin
if input == "q":
break loop
else:
print "you input: ", input
Actually, I have had a glance at some pdf. But I got an imagination, It's difficult to deal with stdin and stdout. Could I have a code example to use stdio?
Following Keelan's instructions, I had finished my little program.
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
From the Clean 2.2 manual, chapter 9:
Concretely, you can make
Start
, which normally has arity 0 (takes no arguments), a function from*World
to*World
. The idea is that we now have a function that changes the world, which means that side effects are allowed (they're not really side effects any more, but operations on the world).The
*
indicates the uniqueness of theWorld
type. This means that you cannot ever have two instances of the world argument. For example, the following will give a compile-time uniqueness error:To use standard IO, you will need functions from the
StdFile
module inStdEnv
. The functions you're going to need are:I simplified the types a bit, actually they're from the class
FileSystem
.stdio
opens a uniqueFile
from a world and also returns the new, modified world.fclose
closes a file in a world, and returns a success flag and the modified world.Then, to read and write from that stdio file, you can use:
freadline
reads a line into a String, including the newline character.fwrites
writes a string to a file, usually you want to include a newline character when writing to stdio.Putting it together:
The
#
syntax might be new to you. It's a kind oflet
which allows you to use the same name for files (or other things), which is more convenient than using, e.g.:Now you should be able to do what you want in pseudocode using a helper function
loop :: *File -> *File
, which calls itself recursively untilq
is inputted.There are more functions than only
freadline
andfwrites
, seeStdFile.dcl
for an idea.