3

I was trying to run the following FParsec code, until by some reason it stopped working:

enter image description here

The error I am getting is

"The value is not a function and cannot be applied."

If I comment out the last line of code (test ns "..") it will not yield an error, though. Any thoughts on how to solve this?


The source code in text form is the following:

open System
open FParsec

let test p str =
    match run p str with
    | Success(result, _, _)   -> printfn "Success: %A" result
    | Failure(errorMsg, _, _) -> printfn "Failure: %s" errorMsg

type Namespace = { Name : string; Classes : string list; }

let classes : Parser<string list, unit> = 
  many (spaces >>. many1Satisfy isLetter .>> spaces)

let ns =
  pipe2 
    (spaces >>. skipString "namespace" >>. spaces >>. many1Satisfy isLetter)
    (spaces >>. skipString "{" >>. classes .>> skipString "}")
    (fun name classes -> { Name = name; Classes = classes } )

test ns "namespace abc { def ghi }"
Mauricio Scheffer
  • 98,863
  • 23
  • 192
  • 275
devoured elysium
  • 101,373
  • 131
  • 340
  • 557

2 Answers2

4

Noone could have guessed the answer here. The problem lied with other thing that I had decided to exclude from the post: the very header of my file:

#if INTERACTIVE
    #r @"C:\Users\xyz\Desktop\fparsec-main-default\Build\VS10\bin\Debug\FParsecCS.dll";
    #r @"C:\Users\xyz\Desktop\fparsec-main-default\Build\VS10\bin\Debug\FParsec.dll";
#endif

Replacing the ; by ;; will make all errors disappear:

#if INTERACTIVE
    #r @"C:\Users\xyz\Desktop\fparsec-main-default\Build\VS10\bin\Debug\FParsecCS.dll";;
    #r @"C:\Users\xyz\Desktop\fparsec-main-default\Build\VS10\bin\Debug\FParsec.dll";;
#endif
devoured elysium
  • 101,373
  • 131
  • 340
  • 557
  • 2
    BTW: You shouldn't need any semicolons or double-semicolons in the (default) lightweight mode. Just `#r @"...."` should be fine. – Tomas Petricek Aug 24 '11 at 20:14
  • Taking the ;; off will again give all the errors described in this thread! – devoured elysium Aug 24 '11 at 20:18
  • 3
    The issue is indentation of the `#r` I think. Don't indent them. – Brian Aug 24 '11 at 20:20
  • @brian: you seem to be right. What is the rationale behind this behaviour, though? – devoured elysium Aug 24 '11 at 20:45
  • 2
    Well, I am surprised you don't get a squiggle on the first `open` after the indented `#r`. But when the first line of code (after `#if` pre-processing) is indented, then the whole 'top level' for the file expects that level of indentation, and it throws off the whole whitespace processing of the file. I am rather surprised that the code (with the last line commented out) compiles without error, as it seems to already be an indentation bug. It appears that the F# 'lexfilter' that handles whitespace-processing may have some inconsistent behavior with regard to `#r`s. – Brian Aug 24 '11 at 21:23
-1

The red underlines clearly show that the compiler thinks that pipe2 is taking four arguments--you should be able to confirm this by added parentheses around the entire test expression like so: (test ns "namespace abs { def ghi })

I'm not sure why though; try putting parentheses around the pipe2 call:

let ns = 
  (pipe2  
     (spaces >>. skipString "namespace" >>. spaces >>. many1Satisfy isLetter) 
     (spaces >>. skipString "{" >>. classes .>> skipString "}") 
     (fun name classes -> { Name = name; Classes = classes } ))
Nathan Shively-Sanders
  • 18,329
  • 4
  • 46
  • 56