[clean-list] Troubles using a function as parameter to another function
Vincent Zweije
zweije@cs.kun.nl
Thu, 14 Feb 2002 22:07:05 +0100
Claudio:
|| 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?
My guess is you have hit the murky depths of uniqueness typing and
lifting.
doProcess is a local function. When it gets lifted, it gets extra
arguments, among which doWork. The closure using the lifted doProcess
gets passed to accFiles, and I suppose accFiles uses that closure in a
non-unique way. This would prevent the required uniqueness on doWork,
since it is part of a non-unique structure (the closure).
I'm afraid I can't think of a workaround right now.
Ciao. Vincent.