pass type to module for abstract data type - heap

I am trying to create a heap module (and eventually priority queue) implemented with an array.
The portion of the heap I have written so far compiles fine:
module MinHeap = {
type elem
type heap = array<elem>
let make = (): heap => []
let insert = (h: heap, e: elem): heap => {
Belt.Array.push(h, e)->ignore
h
}
let next = (h: heap): option<elem> => Belt.Array.get(h, 0)
}
However I cannot instantiate it:
let h = MinHeap.make()
MinHeap.insert(h, 10)->ignore
The build fails with
FAILED: src/use-case-composites/heap-LogicParser.cmj
We've found a bug for you! /Users//projects//src/use-case-composites/heap.res:25:19-20
23 │
24 │ let h = MinHeap.make()
25 │ MinHeap.insert(h, 10)->ignore
26 │
This has type: int
Somewhere wanted: MinHeap.elem
There must be a away to pass types into modules. For example I am able to type option, but how do you do that in a custom module?

If you don't need any behaviour associated with the elem type, you could simply parameterize heap over it, the same way array is:
module MinHeap = {
type heap<'elem> = array<'elem>
let make = (): heap<_> => []
let insert = (h: heap<'elem>, e: 'elem): heap<'elem> => {
Belt.Array.push(h, e)->ignore
h
}
let next = (h: heap<'elem>): option<'elem> => Belt.Array.get(h, 0)
}
Edit: To also answer your question of how to "pass a type into a module", you could do this using a functor:
module type Config = {
type elem
}
module MinHeap = (Config: Config) => {
type elem = Config.elem
type heap = array<elem>
let make = (): heap => []
let insert = (h: heap, e: elem): heap => {
Belt.Array.push(h, e)->ignore
h
}
let next = (h: heap): option<elem> => Belt.Array.get(h, 0)
}
module IntMinHeap = MinHeap({
type elem = int
})
let h = IntMinHeap.make()
IntMinHeap.insert(h, 10)->ignore
It seems a bit overkill for this use case though.

Related

scalaFX - Titledpane: how do I get the heigth of the content?

I created a TiteldPane in scalafx
val titled: TitledPane = new TitledPane()
and put some nodes in it for my GUI.
Later I want to read out the heigth of the content of titled.
In javaFX this would be done with:
((Region) titled.getContent()).getHeight()
But if I try to read the height of the content in scala with:
titled.content.height
the height is marked as deprecated and does not compile. I've got a hint to github (scalafx/issue69) that explains why it is deprecated but does not explain how it can be done instead.
Just to clarify: I want to read out the height of the content of the titledpane, not just titled.heigth.
When titled is closed, then titled.height is 0, but I want to know what it would be when it is expanded (to detect when it has finished expanding actually).
So, how can I do this in scalafx?
EDIT:
Here is a example that shows the described error
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.beans.property.DoubleProperty
import scalafx.beans.value.ObservableValue
import scalafx.collections.ObservableBuffer
import scalafx.event.ActionEvent
import scalafx.scene.Scene
import scalafx.scene.control.cell.TextFieldListCell
import scalafx.scene.control.{Button, ListView, TitledPane}
import scalafx.scene.layout.BorderPane
object TitledPaneEndOfExpansion extends JFXApp {
val expandedHeight = new DoubleProperty()
val data: ObservableBuffer[String] = new ObservableBuffer[String]() ++= List("some", "content", "for", "testing")
stage = new JFXApp.PrimaryStage {
title = "JavaFX: edit after rendering test"
val list: ListView[String] = new ListView[String](data) {
editable = true
cellFactory = TextFieldListCell.forListView()
height.onChange { (source: ObservableValue[Double, Number], oldValue: Number, newValue: Number) =>
expandedHeight.value = titled.content.height
println("old height is: " + oldValue.doubleValue() + " new height is: " + newValue.doubleValue())
if (newValue.doubleValue() == expandedHeight.value) {
edit(1)
}
}
}
val titled: TitledPane = new TitledPane {
text = "titled"
content = list
}
scene = new Scene {
root = new BorderPane {
center = titled
bottom = new Button() {
text = "edit cell 1"
onAction = { _: ActionEvent => list.edit(1) }
}
}
}
expandedHeight.value = titled.content.height //set to 400
list.edit(1)
}
}
And here is the buid.sbt file:
name := "JavaFXrenderingProblem"
version := "0.1"
scalaVersion := "2.13.3"
libraryDependencies += "org.scalafx" %% "scalafx" % "15.0.1-R21"
libraryDependencies += "org.controlsfx" % "controlsfx" % "8.40.18"
// Prevent startup bug in JavaFX
fork := true
// Tell Javac and scalac to build for jvm 1.8
javacOptions ++= Seq("-source", "1.8", "-target", "1.8")
scalacOptions += "-target:jvm-1.8"
scalacOptions += "-feature"
When I just compile with plain sbt i get the compile error-message:
[info] compiling 1 Scala source to ... JavaFXrenderingProblem\target\scala-2.13\classes ...
[error] ... JavaFXrenderingProblem\src\main\scala\TitledPaneEndOfExpansion.scala:38:47: value height is not a member of scalafx.beans.property.ObjectProperty[javafx.scene.Node]
[error] expandedHeight.value = titled.content.height
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 3 s, completed 03.05.2021 11:09:02
I actually get two errors when I execute sbt run on your code, and I do not get a deprecation error:
[info] compiling 1 Scala source to C:\Users\SomeUser\src\SFC\target\scala-2.13\classes ...
[error] C:\Users\SomeUser\src\SFX\src\main\scala\TitledPaneEndOfExpansion.scala:23:41: value height is not a member of scalafx.beans.property.ObjectProperty[javafx.scene.Node]
[error] expandedHeight.value = titled.content.height
[error] ^
[error] C:\Users\MichaelAllen\src\SOSFX\src\main\scala\TitledPaneEndOfExpansion.scala:45:40: value height is not a member of scalafx.beans.property.ObjectProperty[javafx.scene.Node]
[error] expandedHeight.value = titled.content.height //set to 400
[error] ^
[error] two errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 3 s, completed May 3, 2021 9:58:00 AM
From your code, the list value returns the contents of the TitledPane instance, titled, as a ListView[String]. It is this object whose height method you're trying to call. Correct?
The primary problem is that the content method of titled doesn't know enough about the type of the object that titled is storing. All it knows is that it is derived from javafx.scene.Node. Such Node instances do not have a height property, and hence your errors. (It's actually a little more complicated than that, but that's the simplest way to explain the issue.)
However, you already have a reference to the object that is the content of titled: list. So you can replace the second reference to titled.content.height with list.height. The first reference, in list's height's onChanged method, is accessible through the source parameter (it identifies the property that changed value, namely list.height in this case). So you can replace title.content.height with source in this case.
I notice that you're using a DoubleProperty type for expandedHeight in your example, but you need to keep looking at the value of the associated types. That's not very idiomatic. If you don't need this value to be reactive, a simple Double would suffice (but this would require that expandedHeight be declared as a var).
Combined, this produces the following code:
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.beans.property.DoubleProperty
import scalafx.beans.value.ObservableValue
import scalafx.collections.ObservableBuffer
import scalafx.event.ActionEvent
import scalafx.scene.Scene
import scalafx.scene.control.cell.TextFieldListCell
import scalafx.scene.control.{Button, ListView, TitledPane}
import scalafx.scene.layout.BorderPane
object TitledPaneEndOfExpansion extends JFXApp {
var expandedHeight: Double = _
val data: ObservableBuffer[String] = new ObservableBuffer[String]() ++= List("some", "content", "for", "testing")
stage = new JFXApp.PrimaryStage {
title = "JavaFX: edit after rendering test"
val list: ListView[String] = new ListView[String](data) {
editable = true
cellFactory = TextFieldListCell.forListView()
height.onChange { (source: ObservableValue[Double, Number], oldValue: Number, newValue: Number) =>
expandedHeight = source.value
println("old height is: " + oldValue.doubleValue() + " new height is: " + newValue.doubleValue())
if (newValue.doubleValue() == expandedHeight) {
edit(1)
}
}
}
val titled: TitledPane = new TitledPane {
text = "titled"
content = list
}
scene = new Scene {
root = new BorderPane {
center = titled
bottom = new Button() {
text = "edit cell 1"
onAction = { _: ActionEvent => list.edit(1) }
}
}
}
expandedHeight = list.height.value //set to 400
list.edit(1)
}
}
Your code then compiles and runs.
Updated
ScalaFX is simply a wrapper for JavaFX: each JavaFX type has a corresponding ScalaFX type. ScalaFX provides implicit conversion functions to seamlessly convert, say, a JavaFX TitledPane to a ScalaFX TitledPane, and vice versa. However, there's no inheritance relationship between the two sets of objects. That is, a JavaFX TitledPane has no type relationship to a ScalaFX TitledPane. Casting between the two sets of objects is therefore a complicated process.
If you wanted to be able to cast titled.content correctly in order to access the height property of the contents more directly, you would need to get the property's value and explicitly pattern match on the result with the JavaFX version of the object, as follows:
import javafx.scene.control.{ListView => JFXListView}
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.beans.property.DoubleProperty
import scalafx.beans.value.ObservableValue
import scalafx.collections.ObservableBuffer
import scalafx.event.ActionEvent
import scalafx.scene.Scene
import scalafx.scene.control.cell.TextFieldListCell
import scalafx.scene.control.{Button, ListView, TitledPane}
import scalafx.scene.layout.BorderPane
object TitledPaneEndOfExpansion extends JFXApp {
var expandedHeight: Double = _
val data: ObservableBuffer[String] = new ObservableBuffer[String]() ++= List("some", "content", "for", "testing")
stage = new JFXApp.PrimaryStage {
title = "JavaFX: edit after rendering test"
val list: ListView[String] = new ListView[String](data) {
editable = true
cellFactory = TextFieldListCell.forListView()
height.onChange { (source: ObservableValue[Double, Number], oldValue: Number, newValue: Number) =>
expandedHeight = titled.content.value match {
case lv: JFXListView[_] => lv.height.value
case _ => {
throw new RuntimeException(s"Unexpected content type: ${titled.content.getClass.getCanonicalName}")
}
}
println("old height is: " + oldValue.doubleValue() + " new height is: " + newValue.doubleValue())
if (newValue.doubleValue() == expandedHeight) {
edit(1)
}
}
}
val titled: TitledPane = new TitledPane {
text = "titled"
content = list
}
scene = new Scene {
root = new BorderPane {
center = titled
bottom = new Button() {
text = "edit cell 1"
onAction = { _: ActionEvent => list.edit(1) }
}
}
}
expandedHeight = titled.content.value match { //set to 400
case lv: JFXListView[_] => lv.height.value
case _ => throw new RuntimeException(s"Unexpected content type: ${titled.content.getClass.getCanonicalName}")
}
list.edit(1)
}
}
If you didn't have any other means of referencing the list object, that would be your only option.

How to write custom ppx decorator to rescript?

I need to generate a value with a different type from my passed type. This is the first time I write on ocaml-like, and for example, in a familiar me haskell I would use Data.Generics.
How I have understood I need to use decorator and ppx. I wrote simple example
let recordHandler = (loc: Location.t, _recFlag: rec_flag, _t: type_declaration, fields: list(label_declaration)) => {
let (module Builder) = Ast_builder.make(loc);
let test = [%str
let schema: Schema = { name: "", _type: String, properties: [] }
]
let moduleExpr = Builder.pmod_structure(test);
[%str
module S = [%m moduleExpr]
]
}
let str_gen = (~loc, ~path as _, (_rec: rec_flag, t: list(type_declaration))) => {
let t = List.hd(t)
switch t.ptype_kind {
| Ptype_record(fields) => recordHandler(loc, _rec, t, fields);
| _ => Location.raise_errorf(~loc, "schema is used only for records.");
};
};
let name = "my_schema";
let () = {
let str_type_decl = Deriving.Generator.make_noarg(str_gen);
Deriving.add(name, ~str_type_decl) |> Deriving.ignore;
};
And
open Ppxlib;
let _ = Driver.run_as_ppx_rewriter()
But in using in rescript code
module User = {
#deriving(my_schema)
type my_typ = {
foo: int,
};
};
I caught:
schema is not supported
. And I made myself sure me to connect it right when I had changed #deriving(my_schema) for #deriving(abcd) and #deriving(sschema).
I got different error
Ppxlib.Deriving: 'abcd' is not a supported type deriving generator.
And my last experiment was to copy past existing library deriving accessors .
ppx_accessor
I copied-pasted it and renamed for accessors_2. And I got same error such as experiment.
accessors_2 is not supported
Also I haven't found examples "ppx rescript". Can you please help me.
What am I doing wrong (ALL , I know)
I have found answer in the article
Dropping support for custom PPXes such as ppx_deriving (the deriving
attribute is now exclusively interpreted as bs.deriving)

Scala Futures Returning Empty List after Await

I have a program that performs an:
Await.result(Processor.validateEntries(queuedEntries)), Duration.Inf)
And the validateEntries method calls some other method that performs:
val validatedEntries: ListBuffer[Entries] = new ListBuffer[Entries]
for (entry <- queuedEntries) {
checkEntry(entry.name).map(.......... validatedEntries += Entries(...) )
}
Future(validatedEntries.toList)
where checkEntry returns a Future[Boolean].
def checkEntry(name: String): Future[Boolean] = {
checkNameAlreadyExists(name).flatMap(exists =>
buildRequest(exists, name).map(response => {
if (!response.contains("error")) {
true
} else {
false
}
})
)
}
At the top level where I perform the Await.result I also get back an empty list: List(). Any suggestions would greatly help!
Mixing mutable collections and concurrency is not a good idea. Consider refactoring checkEntry to return, say, Future[Option[Entry]] instead of Future[Boolean], where Some would represent successful validation, whilst None unssucessful, and then you might do something like
case class Entry(v: Int)
val queuedEntries = List(Entry(1), Entry(2), Entry(3))
def checkEntry(entry: Entry): Future[Option[Entry]] = ???
Future
.traverse(queuedEntries)(checkEntry)
.map(_.flatten)
If keeping checkEntry as it is, then you might try something like
case class Entry(v: Int)
val queuedEntries = List(Entry(1), Entry(2), Entry(3))
def checkEntry(entry: Entry): Future[Boolean] = Future(Random.nextBoolean)
Future
.traverse(queuedEntries)(checkEntry)
.map(checkedEntries => checkedEntries zip queuedEntries)
.map(_.collect { case (validated, entry) if validated => entry} )
You have to use for comprehension. Basically first you have to read the list and in yield, you have to call function one by one and wait for future to complete by yield
package com.vimit.StackOverflow
import scala.concurrent._
import ExecutionContext.Implicits.global
object FutureProblem extends App {
val list = List(1, 2, 3)
val outputList = List()
val result = for {
value <- list
} yield {
for {
result <- getValue(value).map(res => outputList ++ List(value))
} yield result
}
print(result)
def getValue(value: Int) = Future(value)
}

Module inside an object

I would like to define a parameterized module inside an object by the type of this object.
I have two module interlocked :
(* Parameters*)
module type A = sig
type agent
type intern_agent = { i : agent}
val create : agent -> intern_agent
end
module type E = sig
type event
end
module type StateType = sig
type agent
type event
type state_t = {
mutable name : string;
mutable parentstate : state_t option;
}
end
module State (A : A) (E : E) = struct
type agent = A.agent
type event = E.event
type state_t = {
mutable name : string;
mutable parentstate : state_t option;
}
(*...*)
end
module Agent (S : StateType) =
struct
type agent = S.agent
type event = S.event
type state_t = S.state_t
type agent_t = {
mutable agent : agent ;
}
let create a1 = {
agent = a1;
}
end
(* An implementation of E*)
type event1 = Event1 | Event2;;
module E = struct type event = event1 end;;
What I would like to do is something like that (which is syntacticly incorrect but represents what I would like to do) :
class character = object (self :'self)
val mutable position = (0,0)
val agent =
let A = (module Ag = struct
type agent = 'self
type intern_agent = { i : agent}
let create a = { i = a }
end)
in
let Ag = (module Agent(State(A)(E)) ) in
Ag.create self
method getPosition = position
end;;
How can I write this to be able to define a value which is an Agent parametrized by itself ?
Thank you
Syntactically correct version of a character class definition is
class character = object (self :'self)
val mutable position = (0,0)
val agent =
let module A = struct
type agent = character
type intern_agent = { i : agent}
let create a = { i = a }
end in
let module Ag = Agent(State(A)(E)) in
Ag.create self
method getPosition = position
end
Although, it wont compile, since agent_t will escape the scope of the value agent definition. Indeed, you're asking a compiler to allow you to return a value from a function that has type local to the function.
I wish I can give you some advice on how to redesign your code, but I need more information about your intentions.

Returning a complex data type from arguments with Rhino Mocks

I'm trying to set up a stub with Rhino Mocks which returns a value based on what the parameter of the argument that is passed in.
Example:
//Arrange
var car = new Car();
var provider= MockRepository.GenerateStub<IDataProvider>();
provider.Stub(
x => x.GetWheelsWithSize(Arg<int>.Is.Anything))
.Return(new List<IWheel> {
new Wheel { Size = ?, Make = Make.Michelin },
new Wheel { Size = ?, Make = Make.Firestone }
});
car.Provider = provider;
//Act
car.ReplaceTires();
//Assert that the right tire size was used when replacing the tires
The problem is that I want Size to be whatever was passed into the method, because I'm actually asserting later that the wheels are the right size. This is not to prove that the data provider works obviously since I stubbed it, but rather to prove that the correct size was passed in.
How can I do this?
"This is not to prove that the data provider works ... but rather to prove that
the correct size was passed in."
Not sure if it works that well for this particular case, but generally I've found it easiest to test these sorts of things indirectly via the stub.
Rather than checking the output of the stubbed call, explicitly specify the arguments to your stub and then verify that the return value was used as expected (regardless of the actual data returned). If it was, then you know that your stub was called correctly.
//Arrange
var wheels = new List<IWheel>();
const int wheelSize = 17;
var car = new Car();
car.WheelSize = wheelSize;
var provider= MockRepository.GenerateStub<IDataProvider>();
provider
.Stub(x => x.GetWheelsWithSize(wheelSize))
.Return(wheels);
car.Provider = provider;
//Act
car.ReplaceTires();
//Assert that the right-sized wheels from the provider were
//used when replacing the tires
Assert.That(car.Wheels, Is.SameAs(wheels));
If this approach doesn't work for you in this case then you can use WhenCalled to inspect the call arguments and/or modify the return value.
provider
.Stub(x => x.GetWheelsWithSize(Arg<int>.Is.Anything))
.WhenCalled(x => x.ReturnValue = CreateWheelsOfSize((int) x.Arguments[0]));
In this case CreateWheelsOfSize(int) will just create your list of wheels.
Hope this helps.
You can use the Do() functionality in order to achieve dynamic return value. For example:
[Test]
public void DynamicallyFakeReturnValue()
{
var calculatorStub = MockRepository.GenerateStub<ICalculator>();
calculatorStub.Stub(address => address.AddOne(Arg<int>.Is.Anything))
.Do((Func<int, int>) (x => x - 1));
Assert.That(calculatorStub.AddOne(1), Is.EqualTo(0));
}
In your case it will probably be:
provider.Stub(
x => x.GetWheelsWithSize(Arg<int>.Is.Anything))
.Do((Func<int, List<IWheel>>) (size => new List<IWheel> {
new Wheel { Size = size, Make = Make.Michelin },
new Wheel { Size = size, Make = Make.Firestone }
}));