Waheed Rafiq
Waheed Rafiq

Reputation: 482

Expression was expected to have a type but here has type String

It's my third time today running and this buzz word functional language F# is driving me mad yet when I get certain bits right it feels good

earlier I had a problem with recursive loop someone suggested a way forward and now I am getting the above error, the problem is I know my type is going to be a string so why is the compiler complaining?

Aim was to put 12 weeks of learning into practice so I wanted to work on basic chat bot so far I can hold a basic level conversation, however, there are few things that are still out of my scope for example

why can't I call my type? IUserError to pass user input and check if they have said something that is not in my subject list then to response back with invalid input.

My other issue is to keep things simple I want to convert all input into lowercase string this is also proven to be a challenge.

and then there is numeric at some stage of the conversation user gets to room location for some reason I can find a way other than to do this check.

there is very few tutorial online and the book I am using does not explain things well. I am pleased with what I have achieved so far

if someone can explain where I am going wrong with this because in C# this would have been gone and dusted.:(

here is my whole code feel free to discuss:

open System 
open System.IO
open System.Speech.Synthesis

// required for regular expression
open System.Text.RegularExpressions
  // init randomizer
  let rand = new Random()
  // recursive response function find the first match with a key token 
  // response back acordingly

  // Initialise a new instance of SpeechSynthesizer 
   let voice (sentence: string) =

   use speech = new SpeechSynthesizer(Rate= -3)
   //speech.SelectVoice("Microsoft Huihui Desktop")

   speech.Speak(sentence)

  // define functions  of set list  campus area 
  let mpCampusArea = Set.ofList ["Cisco Labs"; "The Bridge"; "Security 
  Area"; 
   "Mac Labs"; "Open Access"]


   //active patterns  

  //method for checking room number                                                                   

  let chkroom () = 
     let roomNumbers = seq {
      yield 158
      yield 123
      yield 333 }

   printfn "Room not found could it be :"
   for items in roomNumbers do
   printfn "%A" items


  let (|Campuses|None|) users =
  if Regex.Match(users,".*(MP?|mp|Curzon|curzon|ParkSide?).*" ).Success
  then Campuses
  else
    None 

  // Apply Active pattern 
  let(|Repair|None|) input = // any sentence with broken|break|damaged is 
  require repair
   if Regex.Match(input , ".*(broken?|break|damaged?).*").Success 
  then Repair
  else
     None  

 let (|ParkSide|None|) input =
 if Regex.Match(input , ".*(P158|P159|P160).*").Success
 then ParkSide 
 else
     None chkroom


 let (|RoomLocation|None|) str2 =
 if Regex.Match(str2, ".*(158|140|150).*").Success 
 then RoomLocation 
 else
    None chkroom


 // Define an active recognizer for keywords that express salutation.
let (|Bye|Answer|NoSubject|MyGirlFriend|Faulty|None|) input =
match input with
    | "goodbye" | "bye" | "go" |"get lost"
            -> Bye
    | "who" | "how" | "when" |"where"
            -> Answer
    | "car" |"what" |"name" |"bcu"
          -> NoSubject
    | "lonely" |"love" | "friendship"
            -> MyGirlFriend
    | "device" |"software" |"phone"
        ->  Faulty
    | _     
            -> None

 let (|Computer|Other|) input =
 match input with 
 |"goodbye"|"bye"|"go" -> Computer
 |_ -> Other

 // select possible likely hood response based on random number for hello 
 subject 
 // Interact with the user
 // Subject faulty software and Hardware
 let faulty_response (str:string) = 
   let x = rand.Next(5)
   match x with 
   | 0 -> "My advice is to restart the software / hardware?" 
   | 1 -> "My advice is relax it will be sorted."
   | 2 -> "My advice is bin your device / software."
   | 3 -> "Please throw your software / hardware in the recycle bin"
   | 5 -> "Kiss your device / software as this always works for me."
   | _ -> ""


   let  good_bye_response () =
   let b = rand.Next(5)
   match b with 
   | 0 -> "Good bye Babe"
   | 1 -> "Thank God " 
   | 2 -> "We have to be positive love BCU"
   | 3 -> "Live is beautiful but you are a smelly poo little fella BYE!"
   | 4 -> "Good bye and thanks for complainting"
   | _ -> ""


  let answer_response () =
      let x = rand.Next(10)
      match x with 
      | 0 -> "Please go and complait to Waheed Rafiq"
      | 1 -> "Please go and see Emmett Cooper"
      | 2 -> "So you want me to kick a fuss?"
      | 3 -> "What a waste of time"
      | 4 -> "Please go and see BCU tech department"
      | 5 -> "OMG and so what"
      | 6 -> "Jump of the roof it will most likely help us all"
      | 7 -> "Let's talk about the toliet shall we"
      | 8 -> "why don't you use pattern matching with regular expressions!"
      | 9 -> "Speak to the Queen she will  mostly likely deals with BCU 
       complaints"
      | _ -> ""

   let  none_response (str:string) =
     let n = rand.Next(10) 
     match n with 
    | 0 -> "What would  you"+ str + "like to chat about ?" 
    | 1 -> "I do not understand please ask again !"
    | 2 -> "How about you Speak english and I log your helpdesk call yeah?"
    | 3 -> "Sorry to hear that. Are you sure you want to complaint ?"
    | 4 -> "This is a complaint Chat bot where you log helpdesk calls. 
    Please Refer to Cortana for her services.!"


    | 5 -> "Let just complaint yeah for the sake of complaining ?"
    | 6 -> "OKay what is your complaint about ?"
    | 7 -> "Are you a human because you certainly do not behave like one!"
    | 8 -> "The moon is epic. What is broken ?"
    | 9 -> "Do you always complaint? Try logging it like my PC is broken 
        yeah !"
    | _ -> ""


  type Day =
     | Monday
  | Tuesday
  | Wednesday
  | Thursday
  | Friday
  | Saturday
  | Sunday

 let isWeekend x = 
     match x with 
     |Saturday |Sunday -> true
     |_-> false



 // using regular expression to tokenisse line of text 
 let matchWords = Regex(@"\w+")

 let token (text:string) =
     text.ToLowerInvariant()
     |> matchWords.Matches

     // Crossing the stream  
   type IUserError =
      interface
    end

   type Error = { ErrorMessage:string; ErrorCode:int}
         interface IUserError

   type Success = { Status:string }
           interface IUserError

   let error  = {ErrorMessage = "Incorrect input please enter a subject 
   phase"; 
    ErrorCode = 250} :> IUserError

   match error with 
   | :? Error as e -> printfn "Code %i \n Message: %s" e.ErrorCode 
     e.ErrorMessage
   | :? Success -> printfn "Success"
   |_ -> failwith "Invalid option"

   //printfn "%A" error

   //recursive response function
  let rec response (token: string) (str: string) =
  match token with
   | Bye
       -> good_bye_response ()

   | Answer
        -> answer_response ()
   | Faulty
            -> faulty_response  str
   | Repair
        -> 
           sprintf "%s" "Which Campus is the device in?"
   | Campuses
        -> sprintf "%s" "Which room is the device in?"
   | RoomLocation 
        ->  sprintf "%s" "Your call is log. Do you wish to quit?"
   |_ when token.Contains("yes") ->  "Okay logging you out"
   |_ when token.Contains("no") -> answer_response () 
   | NoSubject 
            -> none_response str

   | None when (str.IndexOf(" ") > 0) 
        -> response (str.Substring(0,str.IndexOf(" "))) 
    (str.Substring(str.IndexOf(" ")+1))
   | None when (str.IndexOf(" ") < 0) 
        -> response str ""


   let rec chat () =
   let valueInput = Console.ReadLine()
   printf "Helpdesk-BCU Response --> %s \n" (response "" valueInput)
   let keepRunning, message = response valueInput 
   printfn ">> %s" message
   if keepRunning then chat()




  //let rec chat () =
  //    if Break = false then
  //    let valueInput = Console.ReadLine()
  //    printf "Helpdesk-BCU Response --> %s \n" (response "" valueInput)
 //    if Break = false then 
   //      chat()
      //    else
      //      ChatEnd()

   let BCU_response (str: string) =
   if (str.IndexOf(" ") > 0) then
   response (str.Substring(0,str.IndexOf(" "))) (str.Substring(str.IndexOf(" 
    ")+1)) + "\n"
  else
  response str "" + "\n"

// call back feature for the chatbot 


//[<EntryPoint>]
   //let main argv = printfn "%A" argv


 // Advance expression lamba [ Emmett helps required] 

 let ifancyHerList =
  [
    ("Sara",1); ("Saima",2); ("Zoe",3); ("Scarlett",4);
    ("Jennifer",5);("Sandra Bullock",6)
  ]

 let myGirlFriend () =
 List.pick (fun funToNight  ->
    let n = rand.Next(10)
    if   (snd funToNight) = n
    then Some (fst funToNight)
    else None
  ) ifancyHerList

  //match myGirlFriend with
  //| Some name -> printfn "Your date for tonight is %A lucky fella" name
  //| None      -> printfn "You don't have a date tonight!"
 //

  printfn "Welcome to the BCU Complaint Chat Bot"
  printf "Please enter your first name -->"
  let data = Console.ReadLine()

 //let rec complaints n =
 //    printf "%s what do you want to complain about? -->" data



 //complaints()
 chat()

 printfn "The avaialbe areas at Millennium point are: %A" mpCampusArea
 printfn "Which day is Weekend on?"
 let x = Console.ReadLine()



 0

any helps / pointers / anything as this is driving me nuts

I shall post a link direct to the project file if you wish to download it and have a closer look , much appericate your support.

the link to the project file

Upvotes: 0

Views: 799

Answers (1)

Taylor Fraley
Taylor Fraley

Reputation: 109

I'm not sure using an interface is what you want to do here. You don't have any abstract methods defined for IUserError, but then again maybe you were saving that for later. Also, you have a match with block hanging there with no function.

Here is my interpretation of what you could do:

// Crossing the stream  

type Error = { ErrorMessage:string; ErrorCode:int}
type Success = { Status:string }

type UserError =
  | Error of Error
  | Success of Success

let printResponse (error:UserError) =
  match error with 
  | Error (e) -> printfn "Code %i \n Message: %s" e.ErrorCode e.ErrorMessage
  | Success _ -> printfn "Success"
  |_ -> failwith "Invalid option"

let error  = Error {ErrorMessage = "Incorrect input please enter a subject phase"; ErrorCode = 250}

Using fsi to evaluate printResponse, it should look like this:

> printResponse error;;
Code 250
 Message: Incorrect input please enter a subject phase
val it : unit = ()

Upvotes: 3

Related Questions