How can I get the value of a property given a string argument.
I have a Object CsvProvider.Row which has attributes a,b,c.
I want to get the attribute value depending on property given as a string argument.
I tried something like this:
let getValue (tuple, name: string) =
snd tuple |> Seq.averageBy (fun (y: CsvProvider<"s.csv">.Row) -> y.```name```)
but it gives me the following error:
Unexpected reserved keyword in lambda expression. Expected incomplete
structured construct at or before this point or other token.
Simple invocation of function should look like this:
getValue(tuple, "a")
and it should be equivalent to the following function:
let getValue (tuple) =
snd tuple |> Seq.averageBy (fun (y: CsvProvider<"s.csv">.Row) -> y.a)
Is something like this is even possible?
Thanks for any help!
The CSV type provider is great if you are accessing data by column names statically, because you get nice auto-completion with type inference and checking.
However, for a dynamic access, it might be easier to use the underlying CsvFile (also a part of F# Data) directly, rather than using the type provider:
// Read the given file
let file = CsvFile.Load("c:/test.csv")
// Look at the parsed headers and find the index of column "A"
let aIdx = file.Headers.Value |> Seq.findIndex (fun k -> k = "A")
// Iterate over rows and print A values
for r in file.Rows do
printfn "%A" (r.Item(aIdx))
The only unfortunate thing is that the items are accessed by index, so you need to build some lookup table if you want to easily access them by their name.
Related
I am trying to define a parser in Haskell. I am a total beginner and somehow didn't manage to find any solution to my problem at all.
For the first steps I tried to follow the instructions on the slides of a powerpoint presentation. But I constantly get the error "Not in scope: type variable ‘a’":
type Parser b = a -> [(b,a)]
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x:xs)]
error: Not in scope: type variable ‘a’
|
11 | type Parser b = a -> [(b,a)]
| ^
I don't understand the error but moreover I don't understand the first line of the code as well:
type Parser b = a -> [(b,a)]
What is this supposed to do? On the slide it just tells me that in Haskell, Parsers can be defined as functions. But that doesn't look like a function definition to me. What is "type" doing here? If it s used to specify the type, why not use "::" like in second line above? And "Parser" seems to be a data type (because we can use it in the type definition of "item"). But that doesn't make sense either.
The line derives from:
type Parser = String -> (String, Tree)
The line I used in my code snippet above is supposed to be a generalization of that.
Your help would be much appreciated. And please bear in mind that I hardly know anything about Haskell, when you write an answer :D
There is a significant difference between the type alias type T = SomeType and the type annotation t :: SomeType.
type T = Int simply states that T is just another name for the type Int. From now on, every time we use T, it will be replaced with Int by the compiler.
By contrast, t :: Int indicates that t is some value of type Int. The exact value is to be specified by an equation like t = 42.
These two concepts are very different. On one hand we have equations like T = Int and t = 42, and we can replace either side with the other side, replacing type with types and values with values. On the other hand, the annotation t :: Int states that a value has a given type, not that the value and the type are the same thing (which is nonsensical: 42 and Int have a completely different nature, a value and a type).
type Parser = String -> (String, Tree)
This correctly defines a type alias. We can make it parametric by adding a parameter:
type Parser a = String -> (String, a)
In doing so, we can not use variables in the right hand side that are not parameters, for the same reason we can not allow code like
f x = x + y -- error: y is not in scope
Hence you need to use the above Parser type, or some variation like
type Parser a = String -> [(String, a)]
By contrast, writing
type Parser a = b -> [(b, a)] -- error
would use an undeclared type b, and is an error. At best, we could have
type Parser a b = b -> [(b, a)]
which compiles. I wonder, though, is you really need to make the String type even more general than it is.
So, going back to the previous case, a possible way to make your code run is:
type Parser a = String -> [(a, String)]
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x, xs)]
Note how [(x, xs)] is indeed of type [(Char, String)], as needed.
If you really want to generalize String as well, you need to write:
type Parser a b = b -> [(b, a)]
item :: Parser Char String
item = \inp -> case inp of
[] -> []
(x:xs) -> [(xs, x)]
I imported some data in a Deedle Frame, and I'm trying to convert values type in integer type.
I used the following code:
let myFrmK01 = Frame.ReadCsv(#"QuandlDataSample.csv", hasHeaders=true)
let myFrmK02 = myFrmK01
|> Frame.indexRowsDate "Date"
|> Frame.sortRowsByKey
Now, to convert the values type I tryed with:
let myFrame03 = Frame.mapValues (fun (x:float) -> (Convert.ToUInt64(x * 100.0))) myFrame02
and if I go to see the values of the frame with:
myFrame03.Item("Adj. Open").Item (DateTime(2017, 5, 3))
I find it is still a float.
Where I'm wrong?
Thanks.
You are wrong in taking result of Frame.Item property for the genuine type of the column. The signature of myFrame03.Item("Adj. Open") is string -> Series<DateTime,float>, so the result of individual observation cannot be anything, but float.
If you use another form of Item property
myFrame03.Item("Adj. Open",DateTime(2017, 5, 3))
having the signature string*DateTime -> obj you must see that the observation is unsigned long as expected after you've applied
Frame.mapValues, indeed.
Besides, when in doubt, you can always check actual data frame column types:
myFrame03.ColumnTypes |> Seq.iter (printfn "%A")
I get the following as a result from using the scala json parse.
import scala.util.parsing.json.JSON._
val j: String = """["this",["a","b",["c","d"]]]"""
val parse_test=parseFull(j)
now from this I get a result of Option[Any]
I can use get to obtain the results (in this case I am not concerned about invalid json format, so this should be safe, right?)
parse_test.get
res26: Any = List(this, List(a, b, List(c, d)))
Now, how should I go about going from this Any to the List that I had expected? I assume I should use pattern matching, but I can't figure it out. Any help would be much appreciated
Here is my solution:
scala> val Some(xs # List(_*)) = parse_test
xs: List[Any] = List(this, List(a, b, List(c, d)))
What you could do is a fold with a pattern match and a cast:
test_result.fold[List[String]](Nil){
case _ :: list :: _ => list.asInstanceOf[List[String]]
case _ => Nil
}
Assuming you're trying to throw out of the first element and that the 2nd element is the list you wanted.
Edit:
Be aware that if the 2nd element isn't a list this cast would cause an exception. It's really horrible dealing with a List[Any] and trying to decode what's in there...
I used view here before I was not needed in some parameter, but now I need it and it fails or maybe I'm making something wrong.
here is my try :
member X.CountStatistics ha =
<# linq.IncidentStatistix(ha) #>
|> query
|> Seq.map (fun s -> s.Name, s.Stat)
|> Array.ofSeq
Parameter got bit type. Linq converted it as Nullable (no idea why nullable) and so I pass value there and it fails with
The following construct was used in query but is not recognised by the F#-to-LINQ query translator:
Call (Some (FieldGet (Some (Value (IncidentStats+ins)), LinqBase.FRIIB linq)),
System.Data.Linq.ISingleResult`1[LinqBase.IncidentStatistixResult] IncidentStatistix(System.Nullable`1[System.Boolean]),
[Value (false)])
This is not a valid query expression. Check the specification of permitted queries and consider moving some of the query out of the quotation
what am I doing wrong ?
When calling stored procedure (exposed as a method of DataContext), you don't need to wrap the call inside quotations. It can be executed as a normal method (without query):
member X.CountStatistics ha =
linq.IncidentStatistix(ha)
|> Seq.map (fun s -> s.Name, s.Stat)
|> Array.ofSeq
You can also use sequence comprehensions seq { ... } or array comprehensions [| ... |] to make the additional processing - maybe - a bit nicer:
member X.CountStatistics ha =
[| for s in linq.IncidentStatistix(ha) -> s.Name, s.Stat |]
My current project involves lexing and parsing script code, and as such I'm using fslex and fsyacc. Fslex LexBuffers can come in either LexBuffer<char> and LexBuffer<byte> varieties, and I'd like to have the option to use both.
In order to user both, I need a lexeme function of type ^buf -> string. Thus far, my attempts at specialization have looked like:
let inline lexeme (lexbuf: ^buf) : ^buf -> string where ^buf : (member Lexeme: char array) =
new System.String(lexbuf.Lexeme)
let inline lexeme (lexbuf: ^buf) : ^buf -> string where ^buf : (member Lexeme: byte array) =
System.Text.Encoding.UTF8.GetString(lexbuf.Lexeme)
I'm getting a type error stating that the function body should be of type ^buf -> string, but the inferred type is just string. Clearly, I'm doing something (majorly?) wrong.
Is what I'm attempting even possible in F#? If so, can someone point me to the proper path?
Thanks!
Functions and members marked as inline cannot be overloaded, so your original strategy won't work. You need to write different code for both of the declarations, so you need to use overloading (if you want to write this without boxing and dynamic type tests).
If you're using standard F# tools, then the type you'll get as a buffer will always be LexBuffer<'T> and you want to have two overloads based on the type argument. In this case, you don't need the static member constraints at all and can write just:
type Utils =
static member lexeme(buf:LexBuffer<char>) =
new System.String(buf.Lexeme)
static member lexeme(buf:LexBuffer<byte>) =
System.Text.Encoding.UTF8.GetString(buf.Lexeme)
Are you sure this strategy of redefining inline functions with different argument types can work? Looks like you're trying to overload to me...
type LexBuffer<'a>(data : 'a []) =
member this.Lexeme = data
let lexeme (buf : LexBuffer<'a>) =
match box buf.Lexeme with
| :? (char array) as chArr ->
new System.String(chArr)
| :? (byte array) as byArr ->
System.Text.Encoding.UTF8.GetString(byArr)
| _ -> invalidArg "buf" "must be either char or byte LexBuffer"
new LexBuffer<byte>([| 97uy; 98uy; 99uy |])
|> lexeme
|> printfn "%A"
new LexBuffer<char>([| 'a'; 'b'; 'c' |])
|> lexeme
|> printfn "%A"