I've tried to get all let binding fields of an F# module but am struggling.
System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
|> Seq.collect(fun t -> t.GetFields())
but it doesn't seem to return the bindings. (the code is abbreviated and the types are only modules)
Assuming you want just the let bindings and not any types defined inside the module, you can use the following filters on the module type members:
open System.Reflection
open System.Runtime.CompilerServices
module Test =
type Marker = interface end
let x = 3
let f x = x * x
let m = List.map
let moduleType = typeof<Test.Marker>.DeclaringType
moduleType.GetMembers()
|> Array.filter (fun m -> m.DeclaringType = moduleType)
|> Array.filter (fun m -> m.IsDefined(typeof<CompilerGeneratedAttribute>, true) |> not)
|> Array.filter (fun m -> m.MemberType <> MemberTypes.NestedType)
|> Array.map (fun m -> m.Name)
This will give you back: [|"f"; "m"; "x"|]
Related
I'm trying to invoke the Map.change function. It's clearly defined in the documentation but it just doesn't work for me. I've tried opening different namespaces (such as FSharp.Core, Microsoft.FSharp.Collections), with no success.
open FSharp.Collections
[<EntryPoint>]
let main argv =
let testMap = Map.empty.Add("test", true).Add("otherTest", false)
let newTestMap =
testMap
|> Map.change // Here's the error!
"otherTest"
(fun v ->
match v with
| Some b -> Some (not b)
| None -> None )
printf(newTestMap)
0
I'm getting the following error when trying to run the sample code above:
error FS0039: The value, constructor, namespace or type 'change' is not defined.
How do I use Map.change?
Your code works (apart from the printf). Maybe check your F# or .NET (Core) version. The Collections namespace doesn't have to be open.
let testMap = Map.empty.Add("test", true).Add("otherTest", false)
let newTestMap =
testMap
|> Map.change // Here's the error!
"otherTest"
(fun v ->
match v with
| Some b -> Some (not b)
| None -> None )
printf "%A" newTestMap // map [("otherTest", true); ("test", true)]val it : unit = ()
I'm studying continuations because I want to make some interesting use of coroutines... anyway, I want to better understand one implementation I found.
To do so I want to rewrite the implementation without using the computation expression (continuation Monad), but I'm not quite able to do it.
I have this:
type K<'T,'r> = (('T -> 'r) -> 'r)
let returnK x = (fun k -> k x)
let bindK m f = (fun k -> m (fun a -> f a k))
let runK (c:K<_,_>) cont = c cont
let callcK (f: ('T -> K<'b,'r>) -> K<'T,'r>) : K<'T,'r> =
fun cont -> runK (f (fun a -> (fun _ -> cont a))) cont
type ContinuationBuilder() =
member __.Return(x) = returnK x
member __.ReturnFrom(x) = x
member __.Bind(m,f) = bindK m f
member this.Zero () = this.Return ()
let K = new ContinuationBuilder()
/// The coroutine type from http://fssnip.net/7M
type Coroutine() =
let tasks = new System.Collections.Generic.Queue<K<unit,unit>>()
member this.Put(task) =
let withYield = K {
do! callcK (fun exit ->
task (fun () ->
callcK (fun c ->
tasks.Enqueue(c())
exit ())))
if tasks.Count <> 0 then
do! tasks.Dequeue() }
tasks.Enqueue(withYield)
member this.Run() =
runK (tasks.Dequeue()) ignore
// from FSharpx tests
let ``When running a coroutine it should yield elements in turn``() =
// This test comes from the sample on http://fssnip.net/7M
let actual = System.Text.StringBuilder()
let coroutine = Coroutine()
coroutine.Put(fun yield' -> K {
actual.Append("A") |> ignore
do! yield' ()
actual.Append("B") |> ignore
do! yield' ()
actual.Append("C") |> ignore
do! yield' ()
})
coroutine.Put(fun yield' -> K {
actual.Append("1") |> ignore
do! yield' ()
actual.Append("2") |> ignore
do! yield' ()
})
coroutine.Run()
actual.ToString() = "A1B2C"
``When running a coroutine it should yield elements in turn``()
So, I want rewrite the Put member of the Coroutine class without using the computation expression K.
I have read of course this and this and several other articles about catamorphisms but it is not quite easy to rewrite this continuation monand as it is to rewrite the Write Monad for example...
I try several ways, this is one of them:
member this.Put(task) =
let withYield =
bindK
(callcK (fun exit ->
task (fun () ->
callcK (fun c ->
tasks.Enqueue(c())
exit ()))))
(fun () ->
if tasks.Count <> 0
then tasks.Dequeue()
else returnK ())
tasks.Enqueue(withYield)
Of course it does not work :(
(By the way: there is some extensive documentation of all rules the compiler apply to rewrite the computation in plain F#?)
Your version of Put is almost correct. Two issues though:
The bindK function is being used backwards, the parameters need to be swaped.
task should be passed a Cont<_,_> -> Cont<_,_>, not a unit -> Cont<_,_> -> Cont<_,_>.
Fixing those issues it could look like this:
member this.Put(task) =
let withYield =
bindK
(fun () ->
if tasks.Count <> 0
then tasks.Dequeue()
else returnK ())
(callcK (fun exit ->
task (
callcK (fun c ->
tasks.Enqueue(c())
exit ()))))
tasks.Enqueue(withYield)
Of course it is not too elegant.
When using bind it is better to declare an operator >>=:
let (>>=) c f = bindK f c
that way
do! translates to putting >>= fun () -> after
let! a = translates to putting >>= fun a -> after
and then your code will look a little bit better:
member this.Put2(task) =
let withYield =
callcK( fun exit ->
task( callcK (fun c ->
tasks.Enqueue(c())
exit())
)
) >>= fun () ->
if tasks.Count <> 0 then
tasks.Dequeue()
else returnK ()
tasks.Enqueue withYield
For the following example, Array.mapFold produces the result ([|1; 4; 12|], 7).
let mapping s x = (s * x, s + x)
[| 1..3 |]
|> Array.mapFold mapping 1
Now suppose our mapping is asynchronous.
let asyncMapping s x = async { return (s * x, s + x) }
I am able to create Array.mapFoldAsync for the following to work.
[| 1..3 |]
|> Array.mapFoldAsync asyncMapping 1
|> Async.RunSynchronously
Is there a succinct way to achieve this without creating Array.mapFoldAsync?
I am asking as a way to learn other techniques - my attempts using Array.fold were horrible.
I don't think it would generally be of much benefit to combine mapFold with an Async function, because the expected result is a tuple ('values * 'accumulator), but using an Async function will at best give you an Async<'values * 'accumulator>. Consider the following attempt to make Array.mapFold work with Async:
let mapping s x = async {
let! s' = s
let! x' = x
return (s' * x', s' + x')
}
[| 1..3 |]
|> Array.map async.Return
|> Array.mapFold mapping (async.Return 1)
Even this doesn't work, because of the type mismatch: The type ''a * Async<'b>' does not match the type 'Async<'c * 'd>'.
You may also have noticed that while there is an Array.Parallel.map, there's no Array.Parallel.fold or Array.Parallel.mapFold. If you try to write your own mapFoldAsync, you may see why. The mapping part is pretty easy, just partially apply Array.map and compose with Async.Parallel:
let mapAsync f = Array.map f >> Async.Parallel
You can implement an async fold as well, but since each evaluation depends on the previous result, you can't leverage Async.Parallel this time:
let foldAsync f state array =
match array |> Array.length with
| 0 -> async.Return state
| length ->
async {
let mutable acc = state
for i = 0 to length - 1 do
let! value = f acc array.[i]
acc <- value
return acc
}
Now, when we try to combine these to build a mapFoldAsync, it becomes apparent that we can't leverage parallel execution on the mapping anymore, because both the values and the accumulator can be based on the result of the previous evaluation. That means our mapFoldAsync will be a modified 'foldAsync', not a composition of it with mapAsync:
let mapFoldAsync (f: 's -> 'a -> Async<'b * 's>) (state: 's) (array: 'a []) =
match array |> Array.length with
| 0 -> async.Return ([||], state)
| length ->
async {
let mutable acc = state
let results = Array.init length <| fun _ -> Unchecked.defaultof<'b>
for i = 0 to length - 1 do
let! (x,y) = f acc array.[i]
results.[i] <- x
acc <- y
return (results, acc)
}
While this will give you a way to do a mapFold with an async mapping function, the only real benefit would be if the mapping function did something with high-latency, such as a service call. You won't be able to leverage parallel execution for speed-up. If possible, I would suggest considering an alternative solution, based on your real-world scenario.
Without external libraries (I recommend to try AsyncSeq or Hopac.Streams)
you could do this:
let mapping s x = (fst s * x, snd s + x) |> async.Return
module Array =
let mapFoldAsync folderAsync (state: 'state) (array: 'elem []) = async {
let mutable finalState = state
for elem in array do
let! nextState = folderAsync finalState elem
finalState <- nextState
return finalState
}
[| 1..4 |]
|> Array.mapFoldAsync mapping (1,0)
|> Async.RunSynchronously
It seems like the RTypeProvider can only handle namedParams of the same type. Is this the case?
For example,
open RDotNet
open RProvider
type foo = {
Which: string
Qty: float option
}
let someFoos = [{Which = "that"; Qty = Some 4.0}; {Which = "other"; Qty = Some 2.0}]
let thingForR =
namedParams [
"which", someFoos |> List.map (fun x -> x.Which);
"qty", someFoos |> List.map (fun x -> x.Qty);
]
|> R.data_frame
doesn't work as I get an error on the x.Qty saying
This expression was expected to have type
string
but here has type
float option
If I reverse the order in the thingForR let, then I get the opposite error:
let thingForR =
namedParams [
"qty", someFoos |> List.map (fun x -> x.Qty);
"which", someFoos |> List.map (fun x -> x.Which);
]
|> R.data_frame
Here, the error on x.Which is
This expression was expected to have type
float option
but here has type
string
Can the dictionary in the namedParams not have different types? If so, how can you create a data frame with different types in F# and pass them to R?
You need to box the values inside the dictionary. That way they are all just object. So:
let thingForR =
namedParams [
"which", box (someFoos |> List.map (fun x -> x.Which) );
"qty", box (someFoos |> List.map (fun x -> x.Qty) |> List.map (Option.toNullable >> float));
]
|> R.data_frame
gives me:
val thingForR :
SymbolicExpression = which qty
1 that 4
2 other 2
Please refer to your previous question on float option to convert the Option list to float list. Also string option if necessary.
You can go through Deedle (if not for the option values):
let someFoos' = [{Which = "that"; Qty = 4.0}; {Which = "other"; Qty = 2.0}]
let df' = someFoos' |> Frame.ofRecords
df' |> R.data_frame
open Map
open Pretty
let d_doc () (x : doc) : doc = x
let d_str () = text
let d_map d_k d_v () m : doc =
printf "{%a}"
d_doc
(Map.fold (fun k v acc -> printf "%a, %a -> %a" d_doc acc d_k k d_v v) m (text ""))
tells me "Error: Unbound value Map.fold". How do I do this? (I'd like either a pointer to a reference that explains how to use Map functions (or module functions in general), a standard library pretty printer for maps, and/or a fix for my code.)
I realize this post is old, but for the future visitor, the following works:
module IntMap = Map.Make(Int)
type map = string IntMap.t
let pp_map ppf (m : map) =
IntMap.iter (fun k v -> Format.fprintf ppf "%d -> %s#\n" k v) m
let _ =
IntMap.empty
|> IntMap.add 4 "hello"
|> IntMap.add 2 "world"
|> Format.printf "%a" pp_map
You can print out a map using sexplib quite conveniently. Here's how you'd do it using Core.
open Core.Std
let map = Int.Map.of_alist_exn [1,"one"; 2,"two"; 3,"three"]
let () =
(<:sexp_of<string Int.Map.t>> map)
|> Sexp.to_string_hum
|> print_endline