Is there a way to get a Curried form of the binary operators in SML/NJ? - operators

For example, instead of
- op =;
val it = fn : ''a * ''a -> bool
I would rather have
- op =;
val it = fn : ''a -> ''a -> bool
for use in
val x = getX()
val l = getList()
val l' = if List.exists ((op =) x) l then l else x::l
Obviously I can do this on my own, for example,
val l' = if List.exists (fn y => x = y) l then l else x::l
but I want to make sure I'm not missing a more elegant way.

You could write a helper function that curries a function:
fun curry f x y = f (x, y)
Then you can do something like
val curried_equals = curry (op =)
val l' = if List.exists (curried_equals x) l then l else x::l

My knowledge of SML is scant, but I looked through the Ullman book and couldn't find an easy way to convert a function that accepts a tuple to a curried function. They have two different signatures and aren't directly compatible with one another.
I think you're going to have to roll your own.
Or switch to Haskell.
Edit: I've thought about it, and now know why one isn't the same as the other. In SML, nearly all of the functions you're used to actually accept only one parameter. It just so happens that most of the time you're actually passing it a tuple with more than one element. Still, a tuple is a single value and is treated as such by the function. You can't pass such function a partial tuple. It's either the whole tuple or nothing.
Any function that accepts more than one parameter is, by definition, curried. When you define a function that accepts multiple parameters (as opposed to a single tuple with multiple elements), you can partially apply it and use its return value as the argument to another function.

Related

How to make deeply nested function call polymorphic?

So I have a custom programming language, and in it I am doing some math formalization/modeling. In this instance I am doing basically this (a pseudo-javascript representation):
isIntersection([1, 2, 3], [1, 2], [2, 3]) // => true
isIntersection([1, 2, 3], [1, 2, 3], [3, 4, 5]) // => false
function isIntersection(setTest, setA, setB) {
i = 0
while (i < setTest.length) {
let t = setTest[i]
if (includes(setA, t) || includes(setB, t)) {
i++
} else {
return false
}
}
return true
}
function includes(set, element) {
for (x in set) {
if (isEqual(element, x)) {
return true
}
}
return false
}
function isEqual(a, b) {
if (a is Set && b is Set) {
return isSetEqual(a, b)
} else if (a is X... && b is X...) {
return isX...Equal(a, b)
} ... {
...
}
}
function isSetEqual(a, b) {
i = 0
while (i < a.length) {
let x = a[i]
let y = b[i]
if (!isEqual(x, y)) {
return false
}
i++
}
return true
}
The isIntersection is checking isEqual, and isEqual is configured to be able to handle all kinds of cases of equality check, from sets compared to sets, objects to objects, X's to X's, etc..
The question is, how can we make the isEqual somehow ignorant of the implementation details? Right now you have to have one big if/else/switch statement for every possible type of object. If we add a new type, we have to modify this gigantic isEqual method to add support for it. How can we avoid this, and just define them separately and cleanly?
I was thinking initially of making the objects be "instances of classes" so to speak, with class methods. But I like the purity of having everything just be functions and structs (objects without methods). Is there any way to implement this sort of thing without using classes with methods, instead keeping it just functions and objects?
If not, then how would you implement it with classes? Would it just be something like this?
class Set {
isEqual(set) {
i = 0
while (i < this.length) {
let x = this[i]
let y = set[i]
if (!x.isEqual(y)) {
return false
}
i++
}
return true
}
}
This would mean every object would have to have an isEqual defined on it. How does Haskell handle such a system? Basically looking for inspiration on how this can be most cleanly done. I want to ideally avoid having classes with methods.
Note: You can't just delegate to == native implementation (like assuming this is in JavaScript). We are using a custom programming language and are basically trying to define the meaning of == in the first place.
Another approach is to pass around an isEqual function along with everything somehow, though I don't really see how to do this and if it were possible it would be clunky. So not sure what the best approach is.
Haskell leverages its type and type-class system to deal with polymorphic equality.
The relevant code is
class Eq a where
(==) :: a -> a -> Bool
The English translation is: a type a implements the Eq class if, and only if, it defines a function (==) which takes two inputs of type a and outputs a Bool.
Generally, we declare certain "laws" that type-classes should abide by. For example, x == y should be identical to y == x in all cases, and x == x should never be False. There's no way for the compiler to check these laws, so one typically just writes them into the documentation.
Once we have defined the typeclass Eq in the above manner, we have access to the (==) function (which can be called using infix notation - ie, we can either write (==) x y or x == y). The type of this function is
(==) :: forall a . Eq a => a -> a -> Bool
In other words, for every a that implements the typeclass Eq, (==) is of type a -> a -> Bool.
Consider an example type
data Boring = Dull | Uninteresting
The type Boring has two proper values, Dull and Uninteresting. We can define the Eq implementation as follows:
instance Eq Boring where
Dull == Dull = True
Dull == Uninteresting = False
Uninteresting == Uninteresting = True
Uninteresting == Dull = False
Now, we will be able to evaluate whether two elements of type Boring are equal.
ghci> Dull == Dull
True
ghci> Dull == Uninteresting
False
Note that this is very different from Javascript's notion of equality. It's not possible to compare elements of different types using (==). For example,
ghci> Dull == 'w'
<interactive>:146:9: error:
* Couldn't match expected type `Boring' with actual type `Char'
* In the second argument of `(==)', namely 'w'
In the expression: Dull == 'w'
In an equation for `it': it = Dull == 'w'
When we try to compare Dull to the character 'w', we get a type error because Boring and Char are different types.
We can thus define
includes :: Eq a => [a] -> a -> Bool
includes [] _ = False
includes (x:xs) element = element == x || includes xs element
We read this definition as follows:
includes is a function that, for any type a which implements equality testing, takes a list of as and a single a and checks whether the element is in the list.
If the list is empty, then includes list element will evaluate to False.
If the list is not empty, we write the list as x : xs (a list with the first element as x and the remaining elements as xs). Then x:xs includes element iff either x equals element, or xs includes element.
We can also define
instance Eq a => Eq [a] where
[] == [] = True
[] == (_:_) = False
(_:_) == [] = False
(x:xs) == (y:ys) = x == y && xs == ys
The English translation of this code is:
Consider any type a such that a implements the Eq class (in other words, so that (==) is defined for type a). Then [a] also implements the Eq type class - that is, we can use (==) on two values of type [a].
The way that [a] implements the typeclass is as follows:
The empty list equals itself.
An empty list does not equal a non-empty list.
To decide whether two non-empty lists (x:xs) and (y:ys) are equal, check whether their first elements are equal (aka whether x == y). If the first elements are equal, check whether the remaining elements are equal (whether xs == ys) recursively. If both of these are true, the two lists are equal. Otherwise, they're not equal.
Notice that we're actually using two different ==s in the implementation of Eq [a]. The equality x == y is using the Eq a instance, while the equality xs == ys is recursively using the Eq [a] instance.
In practice, defining Eq instances is typically so simple that Haskell lets the compiler do the work. For example, if we had instead written
data Boring = Dull | Uninteresting deriving (Eq)
Haskell would have automatically generated the Eq Boring instance for us. Haskell also lets us derive other type classes like Ord (where the functions (<) and (>) are defined), show (which allows us to turn our data into Strings), and read (which allows us to turn Strings back into our data type).
Keep in mind that this approach relies heavily on static types and type-checking. Haskell makes sure that we only ever use the (==) function when comparing elements of the same type. The compiler also always knows at compile type which definition of (==) to use in any given situation because it knows the types of the values being compared, so there is no need to do any sort of dynamic dispatch (although there are situations where the compiler will choose to do dynamic dispatch).
If your language uses dynamic typing, this method will not work and you'll be forced to use dynamic dispatch of some variety if you want to be able to define new types. If you use static typing, you should definitely look into Haskell's type class system.

Kotlin: Writing large lambdas similar to Java?

In Java, it is possible to do ->
someList.stream().map(x -> {
y = doSomeOperation(x);
z = doSomeOtherOperation(y);
return z;
}).collect(Collectors.toList());
I need to convert above code to Kotlin. But in all the online tutorials, I am learning that it is only possible to have simple lambdas, like x -> x*x or x->doSomethingThenReturnValue(x).
Is it not possible to write a complex lambda (which does some complex inline operation) like above in kotlin? I tried writing ->
someList.map{ x -> {
y = doSomeOperation(x);
z = doSomeOtherOperation(y);
return z;
}}
But it threw error. Can you please tell what would be the correct way to do it?
I think the problem here is return z. When placed inside lambda it returns from the enclosing function, unlike in Java where it only returns from the lambda itself. So you should write either
someList.map { x ->
y = doSomeOperation(x)
z = doSomeOtherOperation(y)
z
}
or
someList.map { x ->
y = doSomeOperation(x)
z = doSomeOtherOperation(y)
return#map z
}
More details on "return" issue can be found here - https://kotlinlang.org/docs/reference/returns.html
You have written too many brackets. In kotlin, parameter definition for lambdas are set inside the bracket (see reference documentation).
EDIT: Also, return statement in lambdas is not always allowed, and when it is, its behavior is really specific. More information in official documentation.
So, your example needs to be rewritten as following:
someList.map { x ->
val y = doSomeOperation(x)
val z = doSomeOtherOperation(y)
// z implicitely returned as lambda result
z
}

Using FsCheck I get different results on tests, once 100% passed and the other time error

I created a generator to generate lists of int with the same lenght and to test the property of zip and unzip.
Running the test I get once in a while the error
Error: System.ArgumentException: list2 is 1 element shorter than list1
but it shouldn't happen because of my generator.
I got three times the test 100% passed and then the error above. Why?
It seems my generator is not working properly.
let samelength (x, y) =
List.length x = List.length y
let arbMyGen2 = Arb.filter samelength Arb.from<int list * int list>
type MyGenZ =
static member genZip() =
{
new Arbitrary<int list * int list>() with
override x.Generator = arbMyGen2 |> Arb.toGen
override x.Shrinker t = Seq.empty
}
let _ = Arb.register<MyGenZ>()
let pro_zip (xs: int list, ys: int list) =
(xs, ys) = List.unzip(List.zip xs ys)
|> Prop.collect (List.length xs = List.length ys)
do Check.Quick pro_zip
Your code, as written, works for me. So I'm not sure what exactly is wrong, but I can give you a few helpful (hopefully!) hints.
In the first instance, try not using the registrating mechanism, but instead using Prop.forAll, as follows:
let pro_zip =
Prop.forAll arbMyGen2 (fun (xs,ys) ->
(xs, ys) = List.unzip(List.zip xs ys)
|> Prop.collect (List.length xs))
do Check.Quick pro_zip
Note I've also changed your Prop.collect call to collect the length of the list(s), which gives somewhat more interesting output. In fact your property already checks that the lists are the same length (albeit implicitly) so the test will fail with a counterexample if they are not.
Arb.filter transforms an existing Arbitrary (i.e. generator and filter) to a new Arbitrary. In other words, arbMyGen2 has a shrinking function that'll work (i.e. only returns smaller pairs of lists that are of equal length), while in genZip() you throw the shrinker away. It would be fine to simply write
type MyGenZ =
static member genZip() = arbMyGen2
instead.

The signature for this packaged module couldn't be inferred in recursive function

I'm still trying to figure out how to split code when using mirage and it's myriad of first class modules.
I've put everything I need in a big ugly Context module, to avoid having to pass ten modules to all my functions, one is pain enough.
I have a function to receive commands over tcp :
let recvCmds (type a) (module Ctx : Context with type chan = a) nodeid chan = ...
After hours of trial and errors, I figured out that I needed to add (type a) and the "explicit" type chan = a to make it work. Looks ugly, but it compiles.
But if I want to make that function recursive :
let rec recvCmds (type a) (module Ctx : Context with type chan = a) nodeid chan =
Ctx.readMsg chan >>= fun res ->
... more stuff ...
|> OtherModule.getStorageForId (module Ctx)
... more stuff ...
recvCmds (module Ctx) nodeid chan
I pass the module twice, the first time no problem but
I get an error on the recursion line :
The signature for this packaged module couldn't be inferred.
and if I try to specify the signature I get
This expression has type a but an expression was expected of type 'a
The type constructor a would escape its scope
And it seems like I can't use the whole (type chan = a) thing.
If someone could explain what is going on, and ideally a way to work around it, it'd be great.
I could just use a while of course, but I'd rather finally understand these damn modules. Thanks !
The pratical answer is that recursive functions should universally quantify their locally abstract types with let rec f: type a. .... = fun ... .
More precisely, your example can be simplified to
module type T = sig type t end
let rec f (type a) (m: (module T with type t = a)) = f m
which yield the same error as yours:
Error: This expression has type (module T with type t = a)
but an expression was expected of type 'a
The type constructor a would escape its scope
This error can be fixed with an explicit forall quantification: this can be done with
the short-hand notation (for universally quantified locally abstract type):
let rec f: type a. (module T with type t = a) -> 'never = fun m -> f m
The reason behind this behavior is that locally abstract type should not escape
the scope of the function that introduced them. For instance, this code
let ext_store = ref None
let store x = ext_store := Some x
let f (type a) (x:a) = store x
should visibly fail because it tries to store a value of type a, which is a non-sensical type outside of the body of f.
By consequence, values with a locally abstract type can only be used by polymorphic function. For instance, this example
let id x = x
let f (x:a) : a = id x
is fine because id x works for any x.
The problem with a function like
let rec f (type a) (m: (module T with type t = a)) = f m
is then that the type of f is not yet generalized inside its body, because type generalization in ML happens at let definition. The fix is therefore to explicitly tell to the compiler that f is polymorphic in its argument:
let rec f: 'a. (module T with type t = 'a) -> 'never =
fun (type a) (m:(module T with type t = a)) -> f m
Here, 'a. ... is an universal quantification that should read forall 'a. ....
This first line tells to the compiler that the function f is polymorphic in its first argument, whereas the second line explicitly introduces the locally abstract type a to refine the packed module type. Splitting these two declarations is quite verbose, thus the shorthand notation combines both:
let rec f: type a. (module T with type t = a) -> 'never = fun m -> f m

Checking for equality in lists in SML

i want to write a function that checks for equality of lists in SML
for instance :
[1,2,3]=[1,2,3];
val it = true : bool
So instead of writing down the whole thing, i want to make a function that takes two predefined lists, and compare them, so that if list01 is [1,2,3] and list09 is [1,2,3]
then fun equal (list01, list09); will return -val it = true : bool;
You seem to be aware that = works on lists, so (as I already said in my comment) I don't see why you need to define an equal function.
That being said, you can just write:
fun equal (a, b) = (a = b);
Here is a not checked sample:
fun compare ([], []) = true # both empty
| compare (x::xs, y::ys) = (x = y) and compare(xs,ys)
| compare (_, _) = false # different lengths