block, following after 'let' is not finished. Statement required - f#

First of all I want to point out that I could translate the error message in uncorrect way... What is this error about? How should I write my code?
[EntryPoint]
let Main (args:string[]) =
let start = startServer (args.[0])
Console.Read()
I do not understand what should I do to let compiler be happy. Is the following code snippet correct?
let rec handle =
let handler = socket.Accept()
let rec recieveData =
let bytesRec = handler.Receive(bytes)
let data = Encoding.ASCII.GetString(bytes,0,bytesRec)
Console.WriteLine( "Text received : {0}", data)
Console.Read()
0

I can't tell what your code is supposed to do because it has outside dependencies, but at a minimum your problem is indentation: whitespace in F# is significant and in particular plays a significant role in determining lexical scope. So for starters you need to fix indentation, something like
[EntryPoint]
let Main (args:string[]) =
let start = startServer (args.[0])
Console.Read()
let rec handle =
let handler = socket.Accept()
let rec recieveData =
let bytesRec = handler.Receive(bytes)
let data = Encoding.ASCII.GetString(bytes,0,bytesRec)
Console.WriteLine( "Text received : {0}", data)
Console.Read()
0
Also, your employment of rec values appears unnecessary if not incorrect. And it's odd that you perform a bunch of work in the body of the handle let expression only to bind it to 0... do you mean handle or recieveData to be functions? If so maybe you intended something more like
let handle socket = //make handle a function with socket an explicit dependency
let handler = socket.Accept()
let bytesRec = handler.Receive(bytes)
let data = Encoding.ASCII.GetString(bytes,0,bytesRec)
Console.WriteLine( "Text received : {0}", data)
Console.Read() |> ignore //probably you are using Read to wait for user interaction to continue, but just ignore the result (returning unit) instead of returning 0

[<EntryPoint>]
let Main (args : string[]) =
let start = startServer args.[0]
Console.Read()

Related

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

I am new in Ios programming and the below expressing is giving an error:
let combine = date.enumerated().map {index, date in
return (date,self.arrFriendId[index],self.arrFriendName[index],self.arrFriendImage[index],self.arrMsgType[index],self.arrMessage[index], self.arrLastMsgTime[index], self.arrNotifyStatus[index])}
please help me to solve this.
thanks in advance
This error generally occurs when a single expression is doing a lot of things. So compiler tells you to break it to sub-expressions.
Assuming you want the output combine of type Array<Any>, You can do it like this:
let combine = date.enumerated().map { index, date -> Any in
let id = self.arrFriendId[index]
let name = self.arrFriendName[index]
let image = self.arrFriendImage[index]
let messageType = self.arrMsgType[index]
let message = self.arrMessage[index]
let messageTime = self.arrLastMsgTime[index]
let status = self.arrNotifyStatus[index]
return (date, id, name, image, messageType, message, messageTime, status)
}

FSCL error on a simple example

I am trying to use openCL with FSCL on F# but I am obtaining some errors that I don't understand
open FSCL.Compiler
open FSCL.Language
open FSCL.Runtime
open Microsoft.FSharp.Linq.RuntimeHelpers
open System.Runtime.InteropServices
[<StructLayout(LayoutKind.Sequential)>]
type gpu_point2 =
struct
val mutable x: float32
val mutable y: float32
new ( q ,w) = {x=q; y=w}
end
[<ReflectedDefinition>]
let PointSum(a:gpu_point2,b:gpu_point2) =
let sx =(a.x+b.x)
let sy =(a.y+b.y)
gpu_point2(sx,sy)
[<ReflectedDefinition;Kernel>]
let Modgpu(b:float32[], c:float32[],wi:WorkItemInfo) =
let gid = wi.GlobalID(0)
let arp = Array.zeroCreate<gpu_point2> b.Length
let newpoint = gpu_point2(b.[gid],c.[gid])
arp.[gid] <- newpoint
arp
[<ReflectedDefinition;Kernel>]
let ModSum(a:gpu_point2[],b:gpu_point2[],wi:WorkItemInfo) =
let gid = wi.GlobalID(0)
let cadd = Array.zeroCreate<gpu_point2> a.Length
let newsum = PointSum(a.[gid],b.[gid])
cadd.[gid] <- newsum
cadd
[<ReflectedDefinition;Kernel>]
let ModSum2(a:gpu_point2[],b:gpu_point2[],wi:WorkItemInfo) =
let gid = wi.GlobalID(0)
let cadd = Array.zeroCreate<gpu_point2> a.Length
let newsum = gpu_point2(a.[gid].x+b.[gid].x,a.[gid].y+b.[gid].y)
cadd.[gid] <- newsum
cadd
let ws = WorkSize(64L)
let arr_s1= <# Modgpu([|0.f..63.f|],[|63.f..(-1.f)..0.f|],ws)#>.Run()
let arr_s2 = <# Modgpu([|63.f..(-1.f)..0.f|],[|0.f..63.f|],ws)#>.Run()
With this code when I try to use ModSum as
let rsum = <# ModSum(arr_s1,arr_s2,ws)#>.Run()
doesn't work, but instead when I use ModSum2 works perfectly
let rsum = <# ModSum2(arr_s1,arr_s2,ws)#>.Run()
The error I obtain the first time I run it is
FSCL.Compiler.CompilerException: Unrecognized construct in kernel body NewObject (gpu_point2, sx, sy)
and if I re-run the fsi console says
System.NullReferenceException: Object reference not set to an instance of an object.
The only thing I know is that the error doesn't comes from the use of another function since I can define a dot product function that works.
[<ReflectedDefinition>]
let PointProd(a:gpu_point2,b:gpu_point2) =
let f = (a.x*b.x)
let s = (a.y*b.y)
f+s
Thus, I guess the problem comes from the return type of PointSum, but is there a way to create such a function to sum two points and return the point type? And Why is not working?
Edit/Update:
Also with a record happens the same if I define the type as :
[<StructLayout(LayoutKind.Sequential)>]
type gpu_point_2 = {x:float32; y:float32}
If I try to create a function that directly sums two gpu_point_2 on a function works, but if I call a second function it raises the same error as using a struct.
Try to add [<ReflectedDefinition>] on the constructor of gpu_point2:
[<StructLayout(LayoutKind.Sequential)>]
type gpu_point2 =
struct
val mutable x: float32
val mutable y: float32
[<ReflectedDefinition>] new (q, w) = {x=q; y=w}
end
Normally each code that is called from the device need this attribute, constructors included.

Lego Mindstorm: Unable to observe operations after connecting to Lego Brick object

I am unable to observe any operations after I successfully connect to the Lego Brick.
This code works:
let brick = Brick(BluetoothCommunication "COM3")
let result = brick.ConnectAsync().RunSynchronously
However, I am unable to observe any confirmations for successive commands (i.e. sound and motor).
Client Code:
open MyLego.Core
[<EntryPoint>]
let main argv =
let example = LegoExample()
0 // return an integer exit code
Domain Logic
namespace MyLego.Core
open Lego.Ev3.Core
open Lego.Ev3.Desktop
type LegoExample() =
let volume = 100
let frequency = 1000
let duration = 300
let power = 50
let breakSetting = false
let brick = Brick(BluetoothCommunication "COM3")
do brick.BrickChanged.Add(fun e -> printfn "Brick changed")
let result = brick.ConnectAsync().RunSynchronously
let move = brick.DirectCommand.TurnMotorAtPowerForTimeAsync(
OutputPort.B ||| OutputPort.C, power, uint32 duration, breakSetting).RunSynchronously
let playTone = brick.DirectCommand.PlayToneAsync(
volume, uint16 frequency, uint16 duration).RunSynchronously
Note that I am doing all of this in the constructor. Is that okay?
I am referencing the following documentation:
Video
Windows client
It turns out that I have a Bluetooth connection issue.
When I use the USB, I observe the expected behavior.
Apparently the following exception gets swallowed:
"there is no user session key for the specified logon session"
However, this exception is only observed within a C# implementation.

Parsing strings into integers

So I'm trying to find a pattern in a string and convert it to an integer.
Firstly I look for a string:
let haystack = "HTTP/1.1 200\r\n";
let needle = "HTTP/1.";
let http_location = haystack.rfind(needle);
if (http_location.is_some()) {
Now that I've found it I can think of two ways to get the numerical status. Either:
let mut temp_str = haystack.char_at(http_location.unwrap());
let status = String::from_str(temp_str);
}
Or:
let status = String::from_str(&haystack[http_location.unwrap()]);
}
Unfortunately both of them are deprecated (and probably wrong anyway). What is currently the correct way of doing this?
Also, is this part stylistically correct?:
let http_location = haystack.rfind(needle);
if (http_location.is_some())
Parsing is a wide and varied topic. There are easy parsing tools and there are performant parsing tools and a spectrum in between.
fn main() {
let haystack = "HTTP/1.1 200\r\n";
let needle = "HTTP/1.";
let z: Option<u8> = haystack.rfind(needle).and_then(|pt| {
let after_match = &haystack[(pt + needle.len())..];
after_match.splitn(2, " ").next()
}).and_then(|val| {
val.parse().ok()
});
println!("{:?}", z)
}
Here, we use rfind as you did before, which can fail. We use and_then to run the closure if the result was Some. The first closure slices the string after the needle, then splits it on spaces, with a maximum of 2 parts. That can fail, so we use a second and_then to use parse, which can also fail with a Result, so we convert that into an Option to preserve the type.
And the end of this, we still might have failed, as the thing we parsed might not have been a parseable number!
Rust really helps you make explicit places you can fail, and you have to deal with them. ^_^
In this case:
Maybe the string doesn't have "HTTP/1." in it
Iterators have to end at some point, so they can return None.
Parsing a string to a number can fail.
Here's an alternate solution that uses the regex crate:
extern crate regex;
use regex::Regex;
fn main() {
let haystack = "HTTP/1.1 200\r\n";
let re = Regex::new(r"HTTP/1.(\d) (\d+)\r\n").unwrap();
let captures = re.captures(haystack).unwrap();
let version: Option<u8> = captures.at(1).and_then(|version| version.parse().ok());
let status: Option<u8> = captures.at(2).and_then(|version| version.parse().ok());
assert_eq!(Some(1), version);
assert_eq!(Some(200), status);
println!("Version: {:?}, Status: {:?}", version, status);
}
You'll see that we have the same types of failure modes, but the structure is a bit different.
Or maybe a version that uses Result and try!:
#[derive(Debug,Copy,Clone,PartialEq)]
enum Error {
StartNotFound,
NotANumber,
}
fn parse_it(haystack: &str) -> Result<u8, Error> {
let needle = "HTTP/1.";
let pt = try!(haystack.rfind(needle).ok_or(Error::StartNotFound));
let after_match = &haystack[(pt + needle.len())..];
let val = after_match.splitn(2, " ").next().unwrap();
val.parse().map_err(|_| Error::NotANumber)
}
fn main() {
println!("{:?}", parse_it("HTTP/1.1 200\r\n"));
println!("{:?}", parse_it("HTTP/1"));
println!("{:?}", parse_it("HTTP/1.cow"));
}

Reading and updating OpenXML in F#

I can't get this F# code to read and update Content Control text fields inside Word documents.
The second function does absolutely nothing and the first one produces this error: An unhandled exception of type 'System.InvalidOperationException' occurred in System.Core.dll
Additional information: Sequence contains no elements
namespace OpenXML
open DocumentFormat.OpenXml
open DocumentFormat.OpenXml.Packaging
open DocumentFormat.OpenXml.Wordprocessing
open System.Linq
// Add the DocumentFormat.OpenXml assembly
// Add the WindowsBase assembly
module public Word =
let query_plain_text_content_control document_path_and_file_name content_control_tag =
use theDoc = WordprocessingDocument.Open((document_path_and_file_name :string), true)
let mainPart = theDoc.MainDocumentPart
let block = mainPart.Document.Body.Descendants<SdtElement>().Where(fun r -> r.SdtProperties.GetFirstChild<Tag>().Val = content_control_tag).Single()
let t = block.Descendants<Text>().FirstOrDefault()
t.Text
let update_plain_text_content_control document_path_and_file_name content_control_tag new_text = async {
use theDoc = WordprocessingDocument.Open((document_path_and_file_name :string), true)
let mainPart = theDoc.MainDocumentPart
let block = mainPart.Document.Body.Descendants<SdtElement>().Where(fun r -> r.SdtProperties.GetFirstChild<Tag>().Val = content_control_tag).Single()
let t = block.Descendants<Text>().FirstOrDefault()
t.Text <- new_text
mainPart.Document.Save() |> ignore
}
Seems to work fine, with a couple of tweaks:
#r#"DocumentFormat.OpenXml.dll"
#r"WindowsBase.dll"
open DocumentFormat.OpenXml
open DocumentFormat.OpenXml.Packaging
open DocumentFormat.OpenXml.Wordprocessing
open System.Linq
// Add the DocumentFormat.OpenXml assembly
// Add the WindowsBase assembly
module public Word =
let query_plain_text_content_control document_path_and_file_name content_control_tag =
use theDoc = WordprocessingDocument.Open((document_path_and_file_name :string), true)
let mainPart = theDoc.MainDocumentPart
let block = mainPart.Document.Body.Descendants<SdtElement>().Where(fun r -> r.SdtProperties.GetFirstChild<Tag>().Val.ToString() = content_control_tag).Single()
let t = block.Descendants<Text>().FirstOrDefault()
t.Text
let update_plain_text_content_control document_path_and_file_name content_control_tag new_text = async {
use theDoc = WordprocessingDocument.Open((document_path_and_file_name :string), true)
let mainPart = theDoc.MainDocumentPart
let block = mainPart.Document.Body.Descendants<SdtElement>().Where(fun r -> r.SdtProperties.GetFirstChild<Tag>().Val.ToString() = content_control_tag).Single()
let t = block.Descendants<Text>().FirstOrDefault()
t.Text <- new_text
mainPart.Document.Save() |> ignore
}
let oldtext = query_plain_text_content_control #".\text.docx" "ctrltag"
let update = update_plain_text_content_control #".\text.docx" "ctrltag" "new text"
Async.RunSynchronously(update)
let newtext = query_plain_text_content_control #".\text.docx" "ctrltag"
.. on a document containing a single plaintext content control, with tag of 'ctrltag', with content 'old text', I get:
val oldtext : string = "Old text"
val update : Async<unit>
val newtext : string = "new text"
Without calling .ToString() on 'r.SdtProperties.GetFirstChild().Val', I got this error:
The type 'string' is not compatible with the type 'StringValue'.
Perhaps there is a problem with your document? The error you are getting would seem to suggest that there are no content controls with the specified Tag.

Resources