OCaml writing an int list to a byte file - byte

I'm attempting to write a list of integers to a file of bytes with the following code:
let out_channel = open_out_bin "G:\\JVM\\OcamlTest2.class";;
let writeBytes out_channel finalBytes =
match finalBytes with
| [] -> close_out out_channel
| hd::tl -> output_byte out_channel hd; writeBytes out_channel tl;;
And I get the following error:
Error: Unbound value writeBytes
How can I fix this?

Recursive functions defined with let rec in OCaml, see this answer for details.

Related

How to move a String out of a for-loop embedded within a Closure? Rust

New to Rust.
I am attempting to solve: https://leetcode.com/problems/longest-common-prefix/
My own solution is:
impl Solution {
pub fn longest_common_prefix(strs: Vec<String>) -> String {
let first = &strs[0];
let result = strs.iter() // [&string1, &string2, ..., &stringn] for &string in strs
.map(|&string| {
for (i, c) in first.chars().enumerate() {
println!("c is {}", &c);
let mut partial_res = String::new();
if c == string.chars().nth(i).unwrap() {
println!("c is {}", &c);
partial_res.push(c);
}
}
partial_res
}
)
.min_by_key(|string| string.len()).unwrap();
result
}
}
The idea is that for each string in strs, we first iter() them, and map a closure to each of the string.
The closure takes in a &string and compare all the characters of &string and first (which is the first element / string of strs).
Finally, to search for the shortest string in result Iterator and returns the shortest string.
I encounter this error:
Line 16, Char 29: cannot find value `partial_res` in this scope (solution.rs)
|
16 | ... partial_res
| ^^^^^^^^^^^ not found in this scope
For more information about this error, try `rustc --explain E0425`.
error: could not compile `prog` due to previous error
mv: cannot stat '/leetcode/rust_compile/target/release/prog': No such file or directory
Therefore, my question is: > How can I move a String out of a for-loop embedded within a Closure?
Note:
I understand the approach to solving the problem is not ideal, please neglect the algorithmic aspect of the approach here (O(N^2) instead of O(N) algorithm).

Generate random float from Standard Normal distribution and multiply by another float

Trying to generate a random number from the Standard Normal distribution. Need to multiply the value by 0.1 to get the number range i'm looking for. I tried using the documentation from rand_dist you can find here: https://docs.rs/rand_distr/0.3.0/rand_distr/struct.StandardNormal.html
My Cargo.toml is the following:
[package]
name = "test_rng"
version = "0.1.0"
authors = ["Jack"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.7.3"
rand_distr = "0.3.0"
The starting rust code is the example provided in the rand_dist docs from above:
use rand::prelude::*;
use rand_distr::StandardNormal;
fn main() {
let val: f64 = thread_rng().sample(StandardNormal);
println!("{}", val);
}
When I run this it works as expected and the output is:
C:\Users\Jack\Desktop\projects\software\rust\test_rng>cargo run
Compiling test_rng v0.1.0 (C:\Users\Jack\Desktop\projects\software\rust\test_rng)
Finished dev [unoptimized + debuginfo] target(s) in 2.11s
Running `target\debug\test_rng.exe`
0.48398855288705356
C:\Users\Jack\Desktop\projects\software\rust\test_rng>
This is where I'm hitting an issue, when I try to multiply the number by 0.1 in the following code I get the resulting error:
fn main() {
let val: f64 = 0.1 * thread_rng().sample(StandardNormal);
println!("{}", val);
}
C:\Users\Jack\Desktop\projects\software\rust\test_rng>cargo run
Compiling test_rng v0.1.0 (C:\Users\Jack\Desktop\projects\software\rust\test_rng)
error[E0284]: type annotations needed: cannot satisfy `<f64 as std::ops::Mul<_>>::Output == f64`
--> src\main.rs:5:24
|
5 | let val: f64 = 0.1 * thread_rng().sample(StandardNormal);
| ^ cannot satisfy `<f64 as std::ops::Mul<_>>::Output == f64`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0284`.
error: could not compile `test_rng`.
To learn more, run the command again with --verbose.
C:\Users\Jack\Desktop\projects\software\rust\test_rng>
I tried to change 0.1 to 0.1_f64 but that gave the same error.
I tried to convert random number to f64 (which it should already be) with as f64 but that resulted in the following:
fn main() {
let val: f64 = 0.1 * thread_rng().sample(StandardNormal) as f64;
println!("{}", val);
}
C:\Users\Jack\Desktop\projects\software\rust\test_rng>cargo run
Compiling test_rng v0.1.0 (C:\Users\Jack\Desktop\projects\software\rust\test_rng)
error[E0282]: type annotations needed
--> src\main.rs:5:39
|
5 | let val: f64 = 0.1 * thread_rng().sample(StandardNormal) as f64;
| ^^^^^^ cannot infer type for type parameter `T` declared on the associated function `sample`
|
= note: type must be known at this point
help: consider specifying the type arguments in the method call
|
5 | let val: f64 = 0.1 * thread_rng().sample::<T, D>(StandardNormal) as f64;
| ^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.
error: could not compile `test_rng`.
To learn more, run the command again with --verbose.
C:\Users\Jack\Desktop\projects\software\rust\test_rng>
Thought it was a precedence issue so I tried wrapping second half in parenthesis but got the same error.
I can get it to work by making the variable mutable and separating the line into two operations like the following:
fn main() {
let mut val: f64 = thread_rng().sample(StandardNormal);
val *= 0.1;
println!("{}", val);
}
C:\Users\Jack\Desktop\projects\software\rust\test_rng>cargo run
Compiling test_rng v0.1.0 (C:\Users\Jack\Desktop\projects\software\rust\test_rng)
Finished dev [unoptimized + debuginfo] target(s) in 1.62s
Running `target\debug\test_rng.exe`
-0.034993448117065
C:\Users\Jack\Desktop\projects\software\rust\test_rng>
Any idea what is going on with the multiplication of the f64 with the output of the random number?
You can use the following:
fn main() {
let val: f64 = 0.1 * thread_rng().sample::<f64,_>(StandardNormal);
println!("{}", val);
}
This explicitly forces the sample function to return a f64. What was likely going on is that the rust type inference doesn't realize that the RHS needs to be f64, though I'm not sure exactly why.
Edit:
I think some the blame here goes to the definition of sample, in that it uses an unrestricted type parameter. An MVE for this would be:
pub trait Marker{}
impl Marker for f64{}
impl Marker for f32{}
fn does_not_work<T>() -> T{
unimplemented!()
}
fn does_work<T: Marker>() -> T{
unimplemented!()
}
fn main() {
let val: f64 = 0.1 * does_work();
let val: f64 = 0.1 * does_not_work();
}
It's somewhat understandable that the compiler can't infer types for does_not_work, b/c how is it meant to know about every possible type that could multiply with f64? However of we restrict things to only certain types with a trait, then the list of possible types becomes finite and type inference works again.

How do I store a Random number generator in a struct?

I am trying to store a Random number generator in a struct. I can't seem to get the struct definition for any Rng structs to be recognized, like ThreadRng. This works:
use rand::{
self,
distributions::{Distribution, Uniform},
}; // 0.6.4
fn main() {
let mut rng = rand::thread_rng();
let die_range = Uniform::new_inclusive(1, 6);
let die = die_range.sample(&mut rng);
println!("{}", die);
}
However, if I try to define a variable to have the actual type of the Rng, I get an error:
use rand::{
self,
ThreadRng,
distributions::{Distribution, Uniform},
}; // 0.6.4
fn main() {
let mut rng :ThreadRng = rand::thread_rng();
let die_range = Uniform::new_inclusive(1, 6);
let die = die_range.sample(&mut rng);
println!("{}", die);
}
The error is:
error[E0432]: unresolved import `rand::ThreadRng`
--> src/main.rs:3:5
|
3 | ThreadRng,
| ^^^^^^^^^
| |
| no `ThreadRng` in the root
| help: a similar name exists in the module: `thread_rng`
I want to store the Rng in a struct, and I do not want a trait object. How do I import the definition of ThreadRng? Or XorShiftRng (which might be faster - I do not need cryptographic strength)? Is the type in some sub-module I don't know about? All the examples I read online call a method to get the Rng and use it locally; they never store it in a struct and never define any variables that use the struct name.
If you look at the documentation rand::thread_rng, you can click on its return type to see that its fully qualified name is actually rand::rngs::ThreadRng.

How can I factor multiples function that gets their result process by another function?

I would like to factorize this code :
(* This function is applied to the result of functions below *)
let manage_result r s =
match r with
| Error ( `Msg e ) -> Tsdl.Sdl.log s e;exit 1
| Ok a -> a
(* Examples of function I want to factorize, let's call them f_functions, f for factorize *)
let init () =
let flag = Tsdl.Sdl.Init.everything in
let result = Tsdl.Sdl.init flag in
manage_result result "Init error : %s"
let create_window title w h =
let flag = Tsdl.Sdl.Window.windowed in
let result = Tsdl.Sdl.create_window title ~w:w ~h:h flag in
manage_result result "Create window error : %s"
let get_window_surface window =
let result = Tsdl.Sdl.get_window_surface window in
manage_result result "Get window surface error : %s"
As you can see, the two last lines of all of these f_functions are very similar. I would like to make a function that takes as argument a function ( for example, if I wanted to factorize init, the function passed as a parameter would be Tsdl.Sdl.init) and return a function that return the return value of function passed as an argument AND processed through manage_result.
The difficulty is that I don't know how many argument can the f_functions take.
Any other recommendations is appreciated!
Thank you.
A potential solution might be to use the pipe operator rather than naming the intermediary result
let on_error s r = manage_result r s
let create_window title w h =
let flag = Tsdl.Sdl.Window.windowed in
Tsdl.Sdl.create_window title ~w:w ~h:h flag
|> on_error "Create window error : %s"
Going one step further, we could define a custom operator for the error handling
let ( <!> ) = manage_result
which may make your definition lightweight enough
let create_window title w h =
let flag = Tsdl.Sdl.Window.windowed in
Tsdl.Sdl.create_window title ~w:w ~h:h flag
<!> "Create window error : %s"

Unable to initialize a TriMat matrix from the SPRS library

I am trying to use the sparse matrix library SPRS and am having trouble initializing a matrix. Why does this not work?
extern crate sprs;
use sprs::TriMat;
fn main() {
let mut matrix = TriMat::new((5, 5));
}
The error is
error[E0282]: type annotations needed
--> src/main.rs:5:22
|
5 | let mut matrix = TriMat::new((5, 5));
| ---------- ^^^^^^^^^^^ cannot infer type for `N`
| |
| consider giving `matrix` a type
You just need to tell it the type of the elements of the matrix. For example, if it's a matrix of i32 then:
let mut matrix: TriMat<i32> = TriMat::new((5, 5));
This can't be inferred from the new constructor because that only takes an argument for the shape of the matrix, which doesn't include elements of the element type.
If you actually start storing data in the matrix, then the type annotation mostly won't be necessary because it will be inferred from the data:
let mut matrix = TriMat::new((5, 5));
matrix.add_triplet(0, 0, 42); // 42 literal is `i32` by default.
TriMat is:
type TriMat<N> = TriMatI<N, usize>;
TriMatI is:
type TriMatI<N, I> = TriMatBase<Vec<I>, Vec<N>>;
TriMatBase is:
pub struct TriMatBase<IStorage, DStorage> { /* fields omitted */ }
TriMatBase::new is:
pub fn new(shape: (usize, usize)) -> TriMatI<N, I>
Putting those together, you are effectively calling
TriMatBase::<_, usize>::new((5, 5));
The first type parameter is undecidable based on the code you've provided. In many cases, you do something with the value which will allow the compiler to pin down the concrete type. Since you just construct it and throw it away, there's a theoretical infinite number of types this could end up being.
You need to specify the type using the turbofish:
TriMat::<usize>::new((5, 5));
Or an explicit type on the variable:
let matrix: TriMat<usize> = TriMat::new((5, 5));
Or write some more code that will force the compiler to know the concrete type.

Resources