I am getting stuck writing a simple if-then statement in Elm involving signals.
What if the conditional is itself a Signal type? I would like to change the Mouse Down example on the Elm website:
import Graphics.Element exposing (..)
import Mouse
main : Signal Element
main =
Signal.map show Mouse.isDown
It will either say True or False depending on whether the Mouse is up or down. What if I want it to say "Up" or "Down"? My Boolean function could say:
<!-- language: haskell -->
f : Bool -> String
f x =
if x then "↑" else "↓"
but when I change the main function I get a type mismatch.
<!-- language: haskell -->
main : Signal Element
main =
Signal.map show ( f Mouse.isDown)
Error #1:
The 2nd argument to function `map` has an unexpected type.
10| Signal.map show ( f Mouse.isDown)
As I infer the type of values flowing through your program, I see a conflict
between these two types:
Signal a
String
Error #2:
The 1st argument to function `f` has an unexpected type.
10| Signal.map show ( f Mouse.isDown)
As I infer the type of values flowing through your program, I see a conflict
between these two types:
Bool
Signal Bool
It's basically the same thing as with show :: Bool -> Element. You're not passing the Signal into that function, but rather you map the function over the Signal. It works the same with your f:
import Mouse
import Graphics.Element exposing (Element, show)
f : Bool -> String
f x = if x then "↑" else "↓"
updown : Signal String
updown = Signal.map f Mouse.isDown
main : Signal Element
main = Signal.map show updown
Or in short, with composition: main = Signal.map (show << f) Mouse.isDown.
Related
Can I pass an exception as a parameter in an sml function?
If so, would it be something like this?
foo(exc: exception) =
...
Yes, you can, but the type is exn, not exception:
- exception E;
exception E
- E;
val it = E(-) : exn
- exception Q;
exception Q
- fun f x e = if x > 0 then x else raise e;
val f = fn : int -> exn -> int
- f 1 E;
val it = 1 : int
- (f 0 E) handle E => 23 | Q => 49;
val it = 23 : int
- (f 0 Q) handle E => 23 | Q => 49;
val it = 49 : int
But whether it's useful for anything is a different matter.
Yes, you can. The type is exn. Here's an example of where it could be useful:
Say you've got a function that you don't know if terminates or not, and you want to handle this by wrapping it in a function that spawns a thread, calls the function in the thread, sets a timeout and, if the function hasn't returned within the timeout, kills the thread and throws a timeout exception passed in as argument.
The pseudocode could look like:
fun with_timeout t e f =
let val f' = ...run f inside thread...
...wait t time for thread to join...
...otherwise, kill thread and raise e...
in f' end
This function would have the type time -> exn -> ('a -> 'b) -> ('a -> 'b).
You could then write
fun with_timeout_option t f =
let exception Timeout
in SOME (with_timeout t Timeout f)
handle Timeout => NONE
end
and know that this particular Timeout exception can only be handled inside with_timeout_option, because this is the only place that allows pattern matching on it. So if f throws something, it can't be Timeout (it can be another exception called Timeout that shadows this one, or another exception entirely).
Another use-case where passing around exceptions might be useful would be if Standard ML supported pattern matching against an exception that was passed down, but it doesn't. If you have a passed-down exception e, then handle e => ... will interpret e as a variable exception rather than unify the caught exception with the one in your variable. Alas, you always have to handle exceptions statically in the scope they're made available, which is probably a good thing anyway.
I am trying to use Foq to testing an interface with Foq.
So far, all examples I have seen for this have been relatively simple, such as the following:
let users = [|{ID = 1; pass = true};{ID = 2; pass= false}|]
type IFoo =
abstract member Bar: int -> bool
//tests with Foq
let dataAccess =
Mock<IFoo>()
.Setup(fun x-> <# x.Bar(users.[0].ID) #>).Returns(users.[0].pass)
.Setup(fun x-> <# x.Bar(users.[1].ID) #>).Returns(users.[1].pass)
.Create()
The examples have been sourced from 'Testing with F# - Mikael Lundin'
I have also researched this through a bit of googling (this link was helpful - http://trelford.com/blog/post/Foq.aspx)
However, the real Interfaces I want to test are the following:
type IParameters =
abstract member ParameterDate : int->string->DateTime
type IDataSource =
abstract member MortParameters: IParameters
I have tried a number of different ways to test these (e.g. defining a function with a signature of int->string to be used as the input to the setup. Alternatively, having the return value as a string->DateTime and the Setup as just an integer.
My question is really the following: When testing interfaces using Foq, how can I extend the testing to interfaces with function signatures of any general length (e.g. a->b->c->d->e etc.)
Since ParameterDate a property with a function type, you could just set it up as a property that returns a lambda value. See an example of property set-up in Foq. This should be easy to modify for your case:
let instance =
Mock<System.Collections.IList>()
.Setup(fun x -> <# x.Count #>).Returns(1)
.Create()
However, I guess you would lose the ability to have a strict mock with fixed expectations on the function inputs.
To enforce only expected inputs for the function returned by the mock property you could provide a function like this:
fun i s ->
match i, s with
| 1, "" -> DateTime.Now
| _ -> failwith "Invalid mock input"
I would probably stop here, but if you're working with code where you need to verify a function was called, as opposed to just ensuring you get the correct output, you could add a helper like this:
type Verifiable<'a, 'b> (f : 'a -> 'b) =
let called = ref false
member this.Func x =
called := true
f x
member this.Verify() =
if not called.Value then failwith "Mock function was not called"
And here's how you would use it:
let parameterDateMock =
fun i s ->
match i, s with
| 1, "" -> DateTime.Now
| _ -> failwith "Unexpected mock input"
|> Verifiable
let parameters =
{ new IParameters with member this.ParameterDate i s = parameterDateMock.Func i s }
parameters.ParameterDate 1 ""
parameterDateMock.Verify()
Caveat: This only verifies the function was called with at least one parameter. It may have returned another function by currying and not actually run the code in the mock function body. To get around that you'd need a variation of the Verifiable class for every function arity and use the right one in each case.
What I am trying to achieve is similar to a logging facility but for monitoring and streaming arbitrary data from a running simulation. Here is the simplified situation:
module Sim (V:VEC) = struct
module V = V
module M = struct type data = V.t end
let loop n init_data =
let running_data = ref init_data in
for _i = 1 to n do
(*?*) (* monitor here: data => outside world *)
rdata := process_data !rdata
done
end
While simulation loops, at the ? I may want to 'tap' data and accumulate it. Other times, I want to just let it run and disable the data stream with minimal overhead -- the ? is in a tight loop. So I want the streaming to be configurable with little cost.
What I have now is this:
module Sim (V:VEC) = struct
module V = V
module M = struct type data = V.t end
let data_monitor : (M.data -> unit) ref = ref (fun d -> ())
let loop n init_data =
let running_data = ref init_data in
for _i = 1 to n do
!data_monitor !rdata; (* monitor here *)
rdata := process_data !rdata
done
end
Ie. I put a stub monitoring function reference in there. In the actual application script I can then assign a function which e.g. accumulates the data values into a list or some such. It works.
So the question is: is this the best/lowest overhead/nicest way to achieve what I want?
This approach seems a bit hackish, I would rather use the module system instead of function pointers. However, the data type to be streamed is only defined inside the functor Sim. So making a monitoring function in another module Sampler outside of Sim and parametrizing Sim by that, seems not convenient and/or requires duplication of code or recursive modules. I tried, but I was not able to make all types equal.
Edit: Here is roughly what it tried without function refs:
module Sampler (V:VEC) : sig
module V : VEC
type data = V.t
val monitor_data : data -> unit
end
with type data = V.t = struct
module V = V
type data = V.t
let monitor_data data = store_away_the data
end
module Sim (V:VEC) (Sampler:??) : sig
...
end with type M.data = V.t
At the ?? I was not sure how to specify the output signature of Sampler, since the input signature VEC is still free; also I was not sure how exactly to make the type equality work. Maybe I'm doing it wrong here.
As discussed in the comments, you may be able to do something like this using higher-order functions (instead of having to resort to a higher-order functor):
module type VEC = sig type t end
module Vec = struct type t = unit end
module Sim (V : VEC) =
struct
module M = struct type data = V.t list end
let process x = x
let rec loop ?(monitor : M.data -> unit = ignore) n data =
if n <= 0 then data
else
(monitor [];
process data |> loop ~monitor (n - 1))
end
module MySim = Sim (Vec)
let monitor _ = print_endline "foo"
let () =
MySim.loop ~monitor 5 ()
loop above takes an optional function as argument, which you can pass with the syntax ~monitor:my_fun or ~monitor:(fun data -> ...). If you already have a value called monitor in scope, you can simply do ~monitor to pass it. If you don't pass anything, the default value is ignore (i.e. fun _ -> ()).
I also rewrote loop in recursive style. The code above prints foo 5 times. Note that your monitor function can still come from Sampler module, you just have no need to pass the whole module in when instantiating Sim.
EDIT: If you still want to declare a higher-order functor, here is how you do it (...)
EDIT 2: Changed the example given additional information that the reason for the higher-order functor is that there are multiple monitoring functions to call. Note that in this case, there are still other solutions besides a higher-order functor: you could group the functions into a record, and pass the record to loop. Similar to this, you could pass a first-class module. Or, you could create one function that takes a variant type whose cases indicate at what stage the monitoring function is being called, and carry the data associated with each stage. You can also use classes for this, though I wouldn't recommend it. The functor approach does have an advantage, however, if you are committed to declaring M inside Sim.
I have omitted the signature VEC from the sketch because I'm under the impression that the questioner understands where to add it, and there is no problem with it :)
module type SAMPLER =
sig
type data
val monitor : data -> unit
val monitor' : data list -> unit
end
(* These are created inside Sim. *)
module type DATA =
sig
type data
val show : data -> string
end
(* Note that I am using destructive substitution (:=) to avoid the need
to have a type data declared in the body of MySampler below. If you
use a regular type equality constraint, you need to add a field
"type data = Data.data" to the body. *)
module type SAMPLER_FN =
functor (Data : DATA) -> SAMPLER with type data := Data.data
(* This is the higher-order functor (it takes another functor as an
argument). *)
module Sim (Sampler_fn : SAMPLER_FN) =
struct
(* Corresponds to module "Sim.M" in the question. *)
module Data =
struct
type data = string
let show s = s
end
(* Note that without additional type constraints or rearrangements,
the type data is abstract to Sampler (more precisely, Sampler_fn
is parametric over Data). This means that Sampler_fn can't
analyze values of type data, which is why we need to provide
functions such as Data.show to Sampler_fn for instances of
Sampler_fn to be "useful". If you are trying to avoid this and
are having trouble with these specific constraints, let me
know. The ability to pass types and related values (functions
in this case) to Sampler_fn is the main argument in favor of
using a higher-order functor. *)
module Sampler = Sampler_fn (Data)
let simulate x =
(* Call one monitoring function. *)
Sampler.monitor "hi!";
(* Do some computation and call another monitoring function. *)
Sampler.monitor' ["hello"; "world"]
end
Usage:
module MySampler (Data : DATA) =
struct
let monitor data = data |> Data.show |> print_endline
let monitor' data =
data
|> List.map Data.show
|> String.concat " "
|> print_endline
end
module MySim = Sim (MySampler)
let () = MySim.simulate ()
This prints
hi!
hello world
For completeness:
Building on the functor part of antron's answer, this is what I am currently using. It is still a bit involved, and maybe it could be made more concise, but it has some nice advantages. Namely: the monitoring of individual aspects can be switched on and off in a centralized place (a module of type SAMPLER) and arbitrary types can be exported, even if they become defined only somewhere inside the simulator module.
I define the monitoring (=sampling) modules and module types like so:
module type STYPE = sig type t end
module type SSAMPLER = sig
type t
val ev : t React.event
val mon : t -> unit
end
module type SAMPLER_FN = functor (Data : STYPE) -> SSAMPLER
with type t := Data.t
(* stub sampler function for a single one *)
module Never : SAMPLER_FN = functor (Data : STYPE) -> struct
let ev = React.E.never
let mon = ignore
end
(* event primitive generating sampling function *)
module Event : SAMPLER_FN = functor (Data : STYPE) -> struct
let (ev : Data.t React.event), mon' = React.E.create ()
let mon = mon' ?step:None
end
Here, I am using the React library to generate output streams of data. The React.E.never event does nothing and corresponds to sampling being switched off. Then the full sampling configuration is specified like so:
(* the full sampling config *)
module type SAMPLER = sig
val sampler_pos : (module SAMPLER_FN)
val sampler_step : (module SAMPLER_FN)
(* and several more... *)
end
module NoSampling : SAMPLER = struct
let sampler_pos = (module Never: SAMPLER_FN)
let sampler_step = (module Never: SAMPLER_FN)
(* ... *)
end
(* default sampling config *)
module DefaultSampling : SAMPLER = struct
include NoSampling
(* this is only possible when using first class modules *)
let sampler_pos = (module Event : SAMPLER_FN)
end
One could avoid the first-class modules, but then the convenient inclusion and override in DefaultSampling would not be allowed.
In the simulation library code this is used like this:
module type VEC = sig
type t
val zeropos : t
val wiggle : t -> t
end
module Sim (V:VEC) (Sampler:SAMPLER) = struct
module V = V
module M = struct
type t = { mutable pos : V.t }
val create () = { pos=V.zeropos }
module Sampler_pos = (val Sampler.sampler_pos) (struct type nonrec t = t end)
let update f m = m.pos <- f m.pos
end
module Sampler_b = (val Sampler.sampler_b) (struct type t = int end)
let loop n (running_data:M.t) =
for i = 1 to n do
(* monitor step number: *)
Sampler_b.mon i;
(* monitor current pos: *)
Sampler_pos.mon running_data;
M.update V.wiggle running_data
done
end
Here, the sampling functors are applied at appropriate places in the simulation loop. (val ...) is again necessary only because of the first class module wrapping.
Finally, in an application script, one would then do this:
module Simulator = Sim (V) (DefaultSampling);;
let trace = Simulator.M.Sampler_pos.ev
|> React.E.fold (fun l h -> h :: l) []
|> React.S.hold [];;
let init_m = Simulator.M.create () in
Simulator.loop 100 init_m;;
React.S.value trace;;
The last line then contains the accumulated list of values of type Simulator.M.t that occurred during the loop. Monitoring of the step counter (a silly example) is switched off. By making another sampling functor of type SAMPLER and parametrizing Sim by that, one could further customize the monitoring, if desired.
class window =
object
val mutable top_widget = (None : widget option)
method top_widget = top_widget
end
and widget (w : window) =
object
val window = w
method window = window
end;;
There are two things I do not understand:
(None : widget option) what does this mean? Also, in general how do we use 'a option?
(w : window) this means w is a parameter of class widget, which is of type window?
A value of type 'a option has two forms:
None
Some x
Where x is a value of type 'a.
For example here are two values of type int option:
None
Some 421
This is probably obvious, but the idea is that the type represents a value that might or might not be present. The value None represents an absent value.
Yes, the notation (w: window) means that the class widget has a parameter that's a window. When you create a widget it would look like this:
let mywidget = new widget mywindow in
. . .
I'm new to ML and with to have a function that receives a special pre-defined datatype, and able to reference to its entire argument datatype, rather its components.
Here's a stupid example:
datatype frame = Frame of string list * string list
(* Type: fn : string * frame -> frame *)
val lookup_variable_value_in_frame =
fn (string(var), Frame(variables, values)) =>
...
Frame(variables, values)
... ;
1) I want to return the given frame. Must I build another Frame ?
2) I wish to pass the given frame to another function, must I provide a new Frame(variables, values) again ?
I wish I could write somthing like this:
val lookup_variable_value_in_frame =
fn (string(var), frame : Frame(variables, values)) => ...
then I'll be able to use the frame or its components .
Thank you.
Your datatype has already has a name, which is frame. You don't have to build another frame for returning or passing to another function. The first option is using explicit type annotation:
(* Type: fn : string * frame -> frame *)
val lookup_variable_value_in_frame =
fn (var: string, f: frame) =>
...
f
... ;
This option is not common, it should used only when you need types less generic than they are inferred by the type checker. Another option is using as keyword to make another binding to the value:
val lookup_variable_value_in_frame =
fn (var, f as Frame(variables, values)) =>
...(* using f, variables or values here *)
Note that there is no such thing like string(var) in SML, either use var or var: string for explicit type annotation.