SML - Creating dictionary that maps keys to values - function

I need to create a dictionary in sml, but I am having extreme difficulty with an insert function.
type dict = string -> int option
As an example, here is the empty dictionary:
val empty : dict = fn key => NONE
Here is my implementation of an insert function:
fun insert (key,value) d = fn d => fn key => value
But this is of the wrong type, what I need is insert : (string*int) -> dict -> dict.
I've searched everything from lazy functions to implementing dictionaries.
Any help or direction would be greatly appreciateds!
If you are still confused on what I am trying to implement, I drafted up what I should expect to get when calling a simple lookup function
fun lookup k d = d k
- val d = insert ("foo",2) (insert ("bar",3) empty);
val d = fn : string -> int option
- lookup2 "foo" d;
val it = SOME 2 : int option
- lookup2 "bar" d;
val it = SOME 3 : int option
- lookup2 "baz" d;
val it = NONE : int option

You can reason on the signature of the function:
val insert = fn: (string * int) -> dict -> dict
When you supply key, value and a dictionary d, you would like to get back a new dictionary d'. Since dict is string -> int option, d' is a function takes a string and returns an int option.
Suppose you supply a string s to that function. There are two cases which could happen: when s is the same as key you return the associated value, otherwise you return a value by looking up d with key s.
Here is a literal translation:
fun insert (key, value) d = fn s => if s = key then SOME value
else d s

Related

Is it possible to write a recursive grouping function like this in f#

Lets say you had a requirement to group a sequence into a sequence of tuples. Each tuple is a key*seq. So in a sense, the result is a sequence of sequences.
All pretty standard so far.
What if you wanted to further group each sub sequence by some other key? It would be easy enough to map another groupby function onto each element of your sequence of sequences. You would then have a sequence of sequences of sequences.
Starting to get slightly hairy.
What if you wanted to group it even further?
Would it be possible to write a function that can take in a key generating function and an arbitrary sequence, and recursively unwraps the layers and then adds another layer of grouping using the keyFunction?
I suspect the answer is no, because the recursive function would not have a well defined type.
My attempt at this, to further illustrate the idea:
let rec recursiveGrouper keyFunction aSeq =
let first = Seq.head aSeq
match first with
| ((a:'a), _) -> Seq.map (fun (b,(c:seq<'c>)) -> (b, recursiveGrouper keyFunction c)) aSeq
| _ -> Seq.groupBy keyFunction aSeq
EDIT:
Lets add an example of how this might work, it it were possible
type FruitRecord = {Fruit:string; Number:int; SourceFarm:string; Grade:float}
let key1 fr =
fr.Fruit
let key2 fr =
fr.SourceFarm
let key3 fr =
match fr.Grade with
|f when f > 5.0 -> "Very Good"
|f when f > 2.5 -> "Not bad"
|_ -> "Garbage"
Lets say we have a whole bunch of fruit records in a sequence. We want to group them by type of fruit.
One way would be to say
let group1 = fruitRecs |> Seq.groupBy key1
Using our recursive function, this would be
let group1 = recursiveGrouper key1 fruitRecs
Next, lets say we want to group each of the items in the groups of group1 by source farm.
We could say
let group2 =
group1
|> Seq.map (fun (f, s) -> (f, Seq.groupBy key2 s))
Using our recursive function it would be
let group2 = recursiveGrouper key2 group1
And we could go further and group by Grade by saying
let group3 = recursiveGrouper key3 group2
Actually there are some ways to make that recursive function work, using static constraints. Here's a small example:
// If using F# lower than 4.0, use this definition of groupBy
module List =
let groupBy a b = Seq.groupBy a (List.toSeq b) |> Seq.map (fun (a, b) -> a, Seq.toList b) |> Seq.toList
type A = class end // Dummy type
type B = class end // Dummy type
type C =
inherit B
static member ($) (_:C, _:A ) = fun keyFunction -> () // Dummy overload
static member ($) (_:C, _:B ) = fun keyFunction -> () // Dummy overload
static member ($) (_:B, aSeq) = fun keyFunction -> List.groupBy keyFunction aSeq // Ground case overload
static member inline ($) (_:C, aSeq) = fun keyFunction -> List.map (fun (b, c) -> b, (Unchecked.defaultof<C> $ c) keyFunction) aSeq
let inline recursiveGrouper keyFunction aSeq = (Unchecked.defaultof<C> $ aSeq) keyFunction
// Test code
type FruitRecord = {Fruit:string; Number:int; SourceFarm:string; Grade:float}
let key1 fr = fr.Fruit
let key2 fr = fr.SourceFarm
let key3 fr =
match fr.Grade with
|f when f > 5.0 -> "Very Good"
|f when f > 2.5 -> "Not bad"
|_ -> "Garbage"
let fruitRecs = [
{Fruit = "apple" ; Number = 8; SourceFarm = "F"; Grade = 5.5}
{Fruit = "apple" ; Number = 5; SourceFarm = "F"; Grade = 4.5}
{Fruit = "orange"; Number = 8; SourceFarm = "F"; Grade = 5.5}
]
let group1 = recursiveGrouper key1 fruitRecs
let group2 = recursiveGrouper key2 group1
let group3 = recursiveGrouper key3 group2
I don't think you could write it as a recursive function with the sort of constraints you put on yourself - that is:
A tuple 'key * seq<'value> representing the grouping,
A heterogeneous key function (or a collection thereof) - this is what I understand by "group each sub sequence by some other key".
You could make some leeway if you would represent the grouping as an actual tree type (rather than an ad-hoc tree built from tuples) - that way you'd have a well-defined recursive result type to go with your recursive function.
If at that point you would be able to also compromise on the key function to make it homogeneous (worst case - producing a hashcode), you should be able to express what you want within the type system.
You certainly could have a non-recursive grouping function that takes a grouped sequence and puts another level of grouping on top of it - like the one below:
module Seq =
let andGroupBy (projection: 't -> 'newKey) (source: seq<'oldKey * seq<'t>>) =
seq {
for key, sub in source do
let grouped = Seq.groupBy projection sub
for nkey, sub in grouped do
yield (key, nkey), sub
}
Using your FruitRecord example:
values
|> Seq.groupBy key1
|> Seq.andGroupBy key2
|> Seq.andGroupBy key3

How to encode tuple to JSON in elm

I have tuple of (String,Bool) that need to be encoded to JSON Array in elm.
This below link is useful for the primitive types and other list, array and object. But I need to encode tuple2.
Refer : http://package.elm-lang.org/packages/elm-lang/core/4.0.3/Json-Encode#Value
I tried different approach like encoding tuple with toString function.
It does not gives me JSON Array instead it produces String as below "(\"r"\,False)".
JSON.Decoder expecting the input paramater to decode as below snippet.
decodeString (tuple2 (,) float float) "[3,4]"
Refer : http://package.elm-lang.org/packages/elm-lang/core/4.0.3/Json-Decode
Q : When there is decode function available for tuple2, why encode function is missing it.
You can build a generalized tuple size 2 encoder like this:
import Json.Encode exposing (..)
tuple2Encoder : (a -> Value) -> (b -> Value) -> (a, b) -> Value
tuple2Encoder enc1 enc2 (val1, val2) =
list [ enc1 val1, enc2 val2 ]
Then you can call it like this, passing the types of encoders you want to use for each slot:
tuple2Encoder string bool ("r", False)
In elm 0.19 https://package.elm-lang.org/packages/elm/json/latest/Json-Encode a generalized tuple 2 encoder would be
import Json.Encode exposing (list, Value)
tuple2Encoder : ( a -> Value ) -> ( b -> Value ) -> ( a, b ) -> Value
tuple2Encoder enc1 enc2 ( val1, val2 ) =
list identity [ enc1 val1, enc2 val2 ]
Usage:
encode 0 <| tuple2Encoder string int ("1",2)

Functions in scala

I'm having hard time understanding what the following means in scala:
f: Int => Int
Is the a function?
What is the difference between f: Int => Intand def f(Int => Int)?
Thanks
Assuming f: Int => Int is a typo of val f: Int => Int,
and def f(Int => Int) is a typo of def f(i: Int): Int.
val f: Int => Int means that a value f is Function1[Int, Int].
First, A => B equals to =>[A, B].
This is just a shortcut writing, for example:
trait Foo[A, B]
val foo: Int Foo String // = Foo[Int, String]
Second, =>[A, B] equals to Function1[A, B].
This is called "type alias", defined like:
type ~>[A, B] = Foo[A, B]
val foo: Int ~> String // = Foo[Int, String]
def f(i: Int): Int is a method, not a function.
But a value g is Function1[Int, Int] where val g = f _ is defined.
f: Int => Int
means that type of f is Int => Int.
Now what does that mean? It means that f is a function which gets an Int and returns an Int.
You can define such a function with
def f(i: Int): Int = i * 2
or with
def f: Int => Int = i => i * 2
or even with
def f: Int => Int = _ * 2
_ is a placeholder used for designating the argument. In this case the type of the parameter is already defined in Int => Int so compiler knows what is the type of this _.
The following is again equivalent to above definitions:
def f = (i:Int) => i * 2
In all cases type of f is Int => Int.
=>
So what is this arrow?
If you see this arrow in type position (i.e. where a type is needed) it designates a function.
for example in
val func: String => String
But if you see this arrow in an anonymous function it separates the parameters from body of the function. For example in
i => i * 2
To elaborate just slightly on Nader's answer, f: Int => Int will frequently appear in a parameter list for a high order function, so
def myHighOrderFunction(f : Int => Int) : String = {
// ...
"Hi"
}
is a dumb high order function, but shows how you say that myOrderFunction takes as a parameter, f, which is a function that maps an int to an int.
So I might legally call it like this for example:
myHighOrderFunction(_ * 2)
A much more illustrative example comes from Odersky's Programming Scala:
object FileMatcher {
private def filesHere = (new java.io.File(".")).listFiles
private def filesMatching(matcher: String => Boolean) =
for (file <- filesHere if matcher(file.getName))
yield file
def filesEnding(query: String) = filesMatching(_.endsWith(query))
def filesContaining(query: String) = filesMatching(_.contains(query))
def filesRegex(query: String) = filesMatching(_.matches(query))
}
Here filesMatching is a high order function, and we define three other functions that call it passing in different anonymous functions to do different kinds of matching.
Hope that helps.

scala referencing value of a parameter

If I have the following type and function:
object M {
type X[Boolean] = Int => Boolean
def retrieveVal(x: X[Boolean]) : Boolean = //retrieve the Boolean value of x
}
How would I go about retrieving and returning the boolean value?
That is a peculiar type alias. It has a formal type parameter (the name of which is irrelevant and hence the choice of Boolean is misleading) that defines a function from Int to that arbitrary type. You then define a method, retrieveVal that takes a particular kind of X that happens to be X[Boolean] (here Boolean is an actual type parameter and hence is the Boolean we're familiar with) and returns some Boolean. However, the function x passed as an argument requires an Int argument and there is none in evidence.
So, if your retrieveVal were defined like this instead:
def retrieveVal(i: Int, x: X[Boolean]): Boolean = ...
you could define it like this:
def retrieveVal(i: Int, x: X[Boolean]): Boolean = x(i)
To wit:
scala> type X[Boolean] = Int => Boolean
defined type alias X
scala> def retrieveVal(i: Int, x: X[Boolean]): Boolean = x(i)
retrieveVal: (i: Int, x: Int => Boolean)Boolean
scala> retrieveVal(23, i => i % 2 == 0)
res0: Boolean = false

OCaml function typing issue

I'm trying to write a Caml function and I'm having a few troubles with the typing. The function is :
let new_game size count gens =
let rec continueGame board = function
0 -> ()
|n -> drawBoard board size;
continueGame (nextGeneration board) (n-1)
in
continueGame (seedLife (matrix 0 size) count) (gens) ;;
Here are the types of other functions :
val drawBoard : int list list -> int -> unit = <fun>
val seedLife : int list list -> int -> int -> int list list = <fun>
val nextGeneration : int list list -> int list list = <fun>
val matrix : 'a -> int -> 'a list list = <fun>
When trying to evaluate new_Game I have the following error :
continueGame (seedLife (matrix 0 size) count) (gens);;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type int -> int list list
but is here used with type int list list
Why is this error occuring and how can I resolve it?
seedLife takes 3 arguments, but it's only passed 2.