1

Assuming I have *File that I want to read its whole content, and store each line as different element in a list.

My intuitive solution was:

first (x,y) = x

readFile:: *File -> [{#Char}]
readFile file 
    | first (fend (file))   = []
    | otherwise             = [ line : readFile (file)] 
where
    line = first(freadline (file))

Both freadline and fend come from StdFile module:

/**
 * Reads a line from a textfile, including a newline character, except for     the
 * last line. `freadline` cannot be used on data files.
 */
freadline   :: !*File -> (!*{#Char},!*File)

/**
 * @result Whether end-of-file has been reached
 */
fend        :: !*File -> (!Bool,!*File)

But ofcourse I got error since I violated some Uniquness rules:

file demanded attribute cannot be offerd by shared object.

How to avoid this Uniquness problem? I've tried using where to store the value of one freadline, but apparently it doesn't work.

Please consider the fact that I'm new to Clean and the rules of Uniqueness are not very clear to me. Thanks a lot!

Z E Nir
  • 332
  • 1
  • 2
  • 15
  • 1
    This kind of basic functionality is already covered in libraries, in this case in System.File for instance. See https://cloogle.org/src/#Platform/System/File;icl;line=32-45 for its `readAllLines` function which does what you describe. No, it is not possible (should not be) to circumvent uniqueness typing - it is a *feature* of the type system intended to ensure purity of the language while still allowing mutable updates and I/O manipulation. See chapter 9 of the language report for this. –  Mar 10 '19 at 17:59

0 Answers0