[clean-list] Troubles using a function as parameter to another function

Claudio Potenza claudio.potenza@mclink.it
Thu, 14 Feb 2002 19:03:09 +0000


After the "more than one Start rule confuses the IDE" problem (that
was really a bug in the IDE) here is another one:


Unfortunately this involve showing a bit of code; I have tried to reduce 
it to the minimum possible; look at the function "processFiles" in the 
following:


-------------------------------- test.icl
-------------------------------------
module test

import StdEnv,StdLibMisc,Directory

Start :: *World -> String
Start world = processFiles "input.txt" "out.txt" world

/* **************************************************************************
  Given two filenames, opens the first for reading, the second for writing,
  calls the function "doWork" on them, then closes the second one (no need
  to close the first one, opened with "sfopen").
  Returns the result of the "doWork" function
*/
processFiles :: String String *World -> String
processFiles inputName outputName world = result
where
  (result,_) = accFiles doProcess world
  where
    doProcess  :: *Files -> (String,*Files)
    doProcess fileSys
    # (openInOk,inF,fileSys)  = sfopen inputName FReadText fileSys
    | not openInOk            = abort ("cannot open input file "+++inputName)
    # (openOutOk,outF,fileSys)= fopen outputName FWriteText fileSys
    | not openOutOk           = abort ("cannot open output file
"+++outputName)
    # (result,outF,fileSys)   = doWork inF outF fileSys
    # (closeOk,fileSys)       = fclose outF fileSys
    = (result,fileSys)



// **************************************************************************
//  Does some work on the files, needs also the FileSystem as input.
doWork :: File *File *Files -> (String,*File,*Files)
doWork inF outF files
# (filename,_)   = sfreadline inF
# (exist ,files) = existFile files filename
# existStr       = filename+++":"+++toString exist
# outF           = fwrites filename outF
= (existStr,outF,files)


// **************************************************************************
// An auxiliary function
existFile :: *Files String -> (Bool,*Files)
existFile files fullpath
# ((okPath,p),files) = pd_StringToPath fullpath files
| not okPath         = (False,files)
# ((err,info),files) = getFileInfo p files
| err<>NoDirError    = (False,files)
                     = (True,files)
-----------------------------------------------------------------------------


The above code works perfectly well. But I want to be able to pass the
function
"doWork" as a parameter to "processFiles" instead of "hard-coding" it.
But if I do this, namely change Start and "processFiles" as follows::



---------------------- modified sections of test.icl
--------------------------
Start :: *World -> String
Start world = processFiles doWork "input.txt" "out.txt" world


processFiles :: (File *File *Files -> (String,*File,*Files)) String String
*World -> String
processFiles doWork inputName outputName world = result
where
  (result,_) = accFiles doProcess world
  where
    doProcess  :: *Files -> (String,*Files)
    doProcess fileSys
    # (openInOk,inF,fileSys)  = sfopen inputName FReadText fileSys
    | not openInOk            = abort ("cannot open input file "+++inputName)
    # (openOutOk,outF,fileSys)= fopen outputName FWriteText fileSys
    | not openOutOk           = abort ("cannot open output file
"+++outputName)
    # (result,outF,fileSys)   = doWork inF outF fileSys
    # (closeOk,fileSys)       = fclose outF fileSys
    = (result,fileSys)
-----------------------------------------------------------------------------


I get this error:

   Uniqueness error [test.icl,5,Start]:"argument 1 of processFiles" 
   attribute at  indicated position could not be coerced 
   (File -> (*File -> ^ *(*Files -> *(String,*File,*Files))))

I have found a workaround for this by playing around with the definition of
the function "doWork", but it is so ugly I don't want to show it here!
Another strange fact is that if I defined a function "doWork" that doesn't
have the "*Files" parameter, but only the two File, it works!

I cannot understand why this happen (and the exact meaning of the error
message). Am I overlooking something about the uniqueness typing?

thanks


Claudio Potenza
claudio.potenza@mclink.it