Simon Hayward
Simon Hayward

Reputation: 724

Trouble with String.split in F#

I am having trouble with the following code, I am trying to build a lexer.

Again I am using the examples from F# for Scientists.

    let lines_of_file filename =
       seq { use stream = File.OpenRead filename
             use reader = new StreamReader(stream)
             while not reader.EndOfStream do
             yield reader.ReadLine() };;

    let read_matrix filename =
      lines_of_file filename
      |> Seq.map (String.split [' '])
      |> Seq.map (Seq.map float)
      |> Math.Matrix.of_seq;;

I have the following namespaces declared:-

          open System
          open System.IO
          open System.Runtime.Serialization.Formatters.Binary
          open Microsoft.FSharp.Core

But in the read_matrix function the "split" in "Split.string" is not recognised. Also the intellisense does not recognise "Matrix".

I have tried declaring a lot of namespaces to see if they recognise the method, but nothing works (my intellisense does not even recognise System.Math).

I apologise if this is a stupid question, I have looked all over MSDN and elsewhere but I could not find anything.

Can anyone help me to get VS to recognise "split" and "Matrix"?

Many thanks.

Upvotes: 2

Views: 6116

Answers (5)

Rodrigo Rodrigues
Rodrigo Rodrigues

Reputation: 8556

Now with f# 8, they introduced _.Property as a shorthand for fun x -> x.Property. It will make things simpler and reduce the need to open PowerPack or FSharpX just for those convenient module functions wrapping methods and properties.

let read_matrix filename =
  lines_of_file filename
  |> Seq.map _.Split(' ')    // <-- new stuff
  |> Seq.map (Seq.map float)
  |> Math.Matrix.ofSeq

More details in this other answer here.

Upvotes: 0

Daniel
Daniel

Reputation: 47904

There are a few problems. Your casing is wrong. It's Split, not split. It's an instance (not static) method. The separators must be an array, not list. The following works:

let read_matrix filename =
  lines_of_file filename
  |> Seq.map (fun line -> line.Split ' ')
  |> Seq.map (Seq.map float)
  |> Math.Matrix.ofSeq

Incidentally, Math.Matrix.of_seq has been deprecated. It is now Math.Matrix.ofSeq.

Upvotes: 7

Robert Jeppesen
Robert Jeppesen

Reputation: 7877

A common thing to do to make instance methods more natural to use in F# is to define simple helper functions:

let split separators (x:string) = x.Split(separators)
// Can now pipe into it:
lines_of_file filename
|> Seq.map (split [|' '|])

Upvotes: 5

Anas Karkoukli
Anas Karkoukli

Reputation: 1342

As for the Math.Matrix method, it is from the f# powerpack that you need to install...

you can read this Stackoverflow thread.. what-happened-to-microsoft-fsharp-math-matrix

Also for the Split issue.. Split is a method on a string instance.. You can not call it as a static method as you did..

ex: "Some string value".Split([|' '|]) is a correct approach to split a string passing the list of delimiters as an array

Upvotes: 1

Anas Karkoukli
Anas Karkoukli

Reputation: 1342

Also for the Split issue.. Split is a method on a string instance.. You can not call it as a static method as you did..

ex: "Some string value".Split([|' '|]) is a correct approach to split a string passing the list of delimiters as an array

Upvotes: 1

Related Questions