I need to write some function NTimesComposition(f:(int * int -> int), n:int) which receives some function f and integer n and after doing composition of f, n times, like this f(x,(f(x,f(x,y)))) <- (here for example n = 3) I began to write it on smlnj, but it seems more complicated than I thought thanks in advance for any idea:
NTimesComposition(f:(int * int -> int), n:int)
if n = 1 then fn(x,y) => f(x, y ) else NTimesComposition...//here I'm stuck, must be recurstion
You already got it for n = 1 and you most likely just forgot to pass the (x, y) in the recursive call for n > 1. Obviously here it needs to be something of the form fn (x,y) => f (x, ...) where the ... part is where your recursive calls is going to be.
If you had forgot the (x,y) in the recursive part making it fn (x,y) => NTimesComposition (f, n-1) then you would end up building a chain of anonymous functions as "long" as your argument n describes. That would result in a different type of your NTimesComposition function depending on what n you supply which is not valid due to the way SML's type system works (Hindley-Milner).
The following two functions will do the job for you
fun foo (f, 1) = (fn xy => f xy)
| foo (f, n) = (fn (x,y) => f(x, foo (f, n-1) (x,y)))
and
fun baz (f, 1) xy = f xy
| baz (f, n) (x,y) = f(x, foo (f, n-1) (x,y))
where the first resembles your code the most using the anonymous function.
Related
It is a little bit custom issue, is not contrived, but just simplified as possible.
-- this record that has fn that handles both x and y,
-- x and y supposed to be Functors, a arbitrary param for x/y, r is arbitrary result param
type R0 a x y r =
{ fn :: x a -> y a -> r
}
-- this record that has fn that handles only x
type R1 a x r =
{ fn :: x a -> r
}
What I want is a common API (function) that could handle values of R0 and R1 types.
So I do a sum type
data T a x y r
= T0 (R0 a x y r)
| T1 (R1 a x r)
And I declare this function, there is a constraint that x and y have to be Functors.
some :: ∀ a x y r.
Functor x =>
Functor y =>
T a x y r -> a
some = unsafeCoerce -- just stub
Then try to use it.
data X a = X { x :: a}
data Y a = Y { y :: a }
-- make X type functor
instance functorX :: Functor X where
map fn (X val) = X { x: fn val.x }
-- make Y type functor
instance functorY :: Functor Y where
map fn (Y val) = Y { y: fn val.y }
-- declare functions
fn0 :: ∀ a. X a -> Y a -> Unit
fn0 = unsafeCoerce
fn1 :: ∀ a. X a -> Unit
fn1 = unsafeCoerce
Trying to apply some:
someRes0 = some $ T0 { fn: fn0 } -- works
someRes1 = some $ T1 { fn: fn1 } -- error becase it can not infer Y which should be functor but is not present in f1.
So the question is: Is it possible to make such API work somehow in a sensible/ergonomic way (that would not require some addition type annotations from a user of this API)?
I could apparently implement different functions some0 and some1 for handling both cases, but I wonder if the way with a single function (which makes API surface simpler) is possilbe.
And what would be other suggestions for implementing such requirements(good API handling such polymorphic record types that differ in a way described above, when one of the records has exessive params)?
You should make T1 and T0 separate types and then make function some itself overloaded to work with them both:
data T0 x y r a = T0 (R0 a x y r)
data T1 x r a = T1 (R1 a x r)
class Some t where
some :: forall a. t a -> a
instance someT0 :: (Functor x, Functor y) => Some (T0 x y r) where
some = unsafeCoerce
instance someT1 :: Functor x => Some (T1 x r) where
some = unsafeCoerce
An alternative, though much less elegant, solution would be to have the caller of some explicitly specify the y type with a type signature. This is the default approach in situations when a type can't be inferred by the compiler:
someRes1 :: forall a. a
someRes1 = some (T1 { fn: fn1 } :: T a X Y Unit)
Note that I had to add a type signature for someRes1 in order to have the type variable a in scope. Otherwise I couldn't use it in the type signature T a X Y Unit.
An even more alternative way to specify y would be to introduce a dummy parameter of type FProxy:
some :: ∀ a x y r.
Functor x =>
Functor y =>
FProxy y -> T a x y r -> a
some _ = unsafeCoerce
someRes0 = some FProxy $ T0 { fn: fn0 }
someRes1 = some (FProxy :: FProxy Maybe) $ T1 { fn: fn1 }
This way you don't have to spell out all parameters of T.
I provided the latter two solutions just for context, but I believe the first one is what you're looking for, based on your description of the problem mentioning "polymorphic methods". This is what type classes are for: they introduce ad-hoc polymorphism.
And speaking of "methods": based on this word, I'm guessing those fn functions are coming from some JavaScript library, right? If that's the case, I believe you're doing it wrong. It's bad practice to leak PureScript-land types into JS code. First of all JS code might accidentally corrupt them (e.g. by mutating), and second, PureScript compiler might change internal representations of those types from version to version, which will break your bindings.
A better way is to always specify FFI bindings in terms of primitives (or in terms of types specifically intended for FFI interactions, such as the FnX family), and then have a layer of PureScript functions that transform PureScript-typed parameters to those primitives and pass them to the FFI functions.
Reading this article and realized that roughly all the functions after yield keyword is a map function. While all the statements within the for are flatMap functions. Why is that so? Why can the function after the yield be a flatMap function and also the functions within for are map functions?
Your first point is roughly correct. The statement
for (x <- list) yield f(x)
Is equivalent to
list.map(x => f(x))
But you are not quite right about how flatMap is used when there is more than one list.
The flatMap call is used if you want to iterate over another list at the same time:
for (
x <- list1
y <- list2
) yield f(x, y)
This is equivalent to
list1.flatMap(x => list2.map(y => f(x, y)))
The map call is wrapped in a flatMap call so that the result is a simple list. If the outer call was map then the result would be a nested list.
The inner call is always a map call, all the outer calls are flatMap. So
for (
x <- list1
y <- list2
z <- list3
) yield f(x, y, z)
Is
list1.flatMap(x => list2.flatMap(y => list3.map(z => f(x, y, z))))
In the end the best thing to do with for is to experiment with it until it does what you want, and after a while it will become intuitive.
This is a implementation of the Y-combinator in Scala:
scala> def Y[T](func: (T => T) => (T => T)): (T => T) = func(Y(func))(_:T)
Y: [T](func: (T => T) => (T => T))T => T
scala> def fact = Y {
| f: (Int => Int) =>
| n: Int =>
| if(n <= 0) 1
| else n * f(n - 1)}
fact: Int => Int
scala> println(fact(5))
120
Q1: How does the result 120 come out, step by step? Because the Y(func) is defined as func(Y(func)), the Y should become more and more,Where is the Y gone lost and how is the 120 come out in the peform process?
Q2: What is the difference between
def Y[T](func: (T => T) => (T => T)): (T => T) = func(Y(func))(_:T)
and
def Y[T](func: (T => T) => (T => T)): (T => T) = func(Y(func))
They are the same type in the scala REPL, but the second one can not print the result 120?
scala> def Y[T](func: (T => T) => (T => T)): (T => T) = func(Y(func))
Y: [T](func: (T => T) => (T => T))T => T
scala> def fact = Y {
| f: (Int => Int) =>
| n: Int =>
| if(n <= 0) 1
| else n * f(n - 1)}
fact: Int => Int
scala> println(fact(5))
java.lang.StackOverflowError
at .Y(<console>:11)
at .Y(<console>:11)
at .Y(<console>:11)
at .Y(<console>:11)
at .Y(<console>:11)
First of all, note that this is not a Y-combinator, since the lambda version of the function uses the free variable Y. It is the correct expression for Y though, just not a combinator.
So, let’s first put the part which computes the factorial into a separate function. We can call it comp:
def comp(f: Int => Int) =
(n: Int) => {
if (n <= 0) 1
else n * f(n - 1)
}
The factorial function can now be constructed like this:
def fact = Y(comp)
Q1:
Y is defined as func(Y(func)). We invoke fact(5) which is actually Y(comp)(5), and Y(comp) evaluates to comp(Y(comp)). This is the key point: we stop here because comp takes a function and it doesn’t evaluate it until needed. So, the runtime sees comp(Y(comp)) as comp(???) because the Y(comp) part is a function and will be evaluated only when (if) needed.
Do you know about call-by-value and call-by-name parameters in Scala? If you declare your parameter as someFunction(x: Int), it will be evaluated as soon as someFunction is invoked. But if you declare it as someFunction(x: => Int), then x will not be evaluated right away, but at the point where it is used. Second call is “call by name” and it is basically defining your x as a “function that takes nothing and returns an Int”. So if you pass in 5, you are actually passing in a function that returns 5. This way we achieve lazy evaluation of function parameters, because functions are evaluated at the point they are used.
So, parameter f in comp is a function, hence it is only evaluated when needed, which is in the else branch. That’s why the whole thing works - Y can create an infinite chain of func(func(func(func(…)))) but the chain is lazy. Each new link is computed only if needed.
So when you invoke fact(5), it will run through the body into the else branch and only at that point f will be evaluated. Not before. Since your Y passed in comp() as parameter f, we will dive into comp() again. In the recursive call of comp() we will be calculating the factorial of 4. We will then again go into the else branch of the comp function, thus effectively diving into another level of recursion (calculating factorial of 3). Note that in each function call your Y provided a comp as an argument to comp, but it is only evaluated in the else branch. Once we get to the level which calculates factorial of 0, the if branch will be triggered and we will stop diving further down.
Q2:
This
func(Y(func))(_:T)
is syntax sugar for this
x => func(Y(func))(x)
which means we wrapped the whole thing into a function. We didn’t lose anything by doing this, only gained.
What did we gain? Well, it’s the same trick as in the answer to a previous question; this way we achieve that func(Y(func)) will be evaluated only if needed since it’s wrapped in a function. This way we will avoid an infinite loop. Expanding a (single-paramter) function f into a function x => f(x) is called eta-expansion (you can read more about it here).
Here’s another simple example of eta-expansion: let’s say we have a method getSquare() which returns a simple square() function (that is, a function that calculates the square of a number). Instead of returning square(x) directly, we can return a function that takes x and returns square(x):
def square(x: Int) = x * x
val getSquare: Int => Int = square
val getSquare2: Int => Int = (x: Int) => square(x)
println(square(5)) // 25
println(getSquare(5)) // 25
println(getSquare2(5)) // 25
Hope this helps.
Complementing the accepted answer,
First of all, note that this is not a Y-combinator, since the lambda version of the function uses the free variable Y. It is the correct expression for Y though, just not a combinator.
A combinator isn't allowed to be explicitly recursive; it has to be a lambda expression with no free variables, which means that it can't refer to its own name in its definition. In the lambda calculus it is not possible to refer to the definition of a function in a function body. Recursion may only be achieved by passing in a function as a parameter.
Given this, I've copied the following implementation from rosetta code that uses some type trickery to implement Y combinator without explicit recursion. See here
def Y[A, B](f: (A => B) => (A => B)): A => B = {
case class W(wf: W => A => B) {
def get: A => B =
wf(this)
}
val g: W => A => B = w => a => f(w.get)(a)
g(W(g))
}
Hope this helps with the understanding.
I don't know the answer, but will try to guess. Since you have def Y[T](f: ...) = f(...) compiler can try to substitute Y(f) with simply f. This will create an infinite sequence of f(f(f(...))). Partially applying f you create a new object, and such substitution becomes impossible.
I have a Scala Map:
x: [b,c]
y: [b,d,e]
z: [d,f,g,h]
I want inverse of this map for look-up.
b: [x,y]
c: [x]
d: [x,z] and so on.
Is there a way to do it without using in-between mutable maps
If its not a multi-map - Then following works:
typeMap.flatMap { case (k, v) => v.map(vv => (vv, k))}
EDIT: fixed answer to include what Marth rightfully pointed out. My answer is a bit more lenghty than his as I try to go through each step and not use the magic provided by flatMaps for educational purposes, his is more straightforward :)
I'm unsure about your notation. I assume that what you have is something like:
val myMap = Map[T, Set[T]] (
x -> Set(b, c),
y -> Set(b, d, e),
z -> Set(d, f, g, h)
)
You can achieve the reverse lookup as follows:
val instances = for {
keyValue <- myMap.toList
value <- keyValue._2
}
yield (value, keyValue._1)
At this point, your instances variable is a List of the type:
(b, x), (c, x), (b, y) ...
If you now do:
val groupedLookups = instances.groupBy(_._1)
You get:
b -> ((b, x), (b, y)),
c -> ((c, x)),
d -> ((d, y), (d, z)) ...
Now we want to reduce the values so that they only contain the second part of each pair. Therefore we do:
val reverseLookup = groupedLookup.map(_._1 -> _._2.map(_._2))
Which means that for every pair we maintain the original key, but we map the list of arguments to something that only has the second value of the pair.
And there you have your result.
(You can also avoid assigning to an intermediate result, but I thought it was clearer like this)
Here is my simplification as a function:
def reverseMultimap[T1, T2](map: Map[T1, Seq[T2]]): Map[T2, Seq[T1]] =
map.toSeq
.flatMap { case (k, vs) => vs.map((_, k)) }
.groupBy(_._1)
.mapValues(_.map(_._2))
The above was derived from #Diego Martinoia's answer, corrected and reproduced below in function form:
def reverseMultimap[T1, T2](myMap: Map[T1, Seq[T2]]): Map[T2, Seq[T1]] = {
val instances = for {
keyValue <- myMap.toList
value <- keyValue._2
} yield (value, keyValue._1)
val groupedLookups = instances.groupBy(_._1)
val reverseLookup = groupedLookups.map(kv => kv._1 -> kv._2.map(_._2))
reverseLookup
}
type Set = Int => Boolean
/**
* Returns whether all bounded integers within `s` satisfy `p`.
*/
def forall(s: Set, p: Int => Boolean): Boolean = {
def iter(a: Int): Boolean = {
if (a > bound) true
else if (contains(s, a) && !p(a)) false
else iter(a + 1)
}
iter(-bound)
}
/**
* Returns whether there exists a bounded integer within `s`
* that satisfies `p`.
*/
def exists(s: Set, p: Int => Boolean): Boolean = !forall(s, (x => !p(x)))
/**
* Returns a set transformed by applying `f` to each element of `s`.
*/
def map(s: Set, f: Int => Int): Set = (x => exists(s, (y: Int) => f(y) ==
x))
so for this piece of code. I don't understand function map.
I see its input are 2 arguments, which are set and method f. But the "body" part, I tried so hard but still don't get it. And what is that "y", and why using f(y) == x makes it apply method f to set elemtns?
need some explanation for me.
thank you!
To be succinct:
If you say: val set2 = map(set1, f),
then set2(x) will returns true if and only if there exits y in set1 such as f(y) == x
That's exactly what exists(set1, y => f(y) == x) is checking.
To put it an other way, an integer is in set2 only if you can obtain it by applying f to an element of set1.
We can try to understand this piece of code by applying it backwards.
The map method here would return true for every given x and function f, if x is a result of the function f applied to the elements of the original set.
It is done by checking that if we go over the original map and apply f to every element of this map, at least one of them will be equal to x (that is what the part (x => exists(s, (y: Int) => f(y) == x)) does).
Regarding exists itself, it is a statement that if we go over all elements of the set (using forall method) with a given predicate p, for at least one of the elements this predicate will not be false (this is the part !forall(s, (x => !p(x)))).
And what is that "y"
exists takes a function Int => Boolean as its second argument. This function is (y: Int) => f(y) == x, and y is simply the name we give to its argument, same as x in x => !p(x).
and why using f(y) == x makes it apply method f to set elemtns?
This definition says "x is a member of map(s, f) when exists(s, y => f(y) == x). Now consider a simple case: s is the set {1, 2} represented by a function x => (x == 1) || (x == 2), and f = z => z + 1 over it. Then we have
s2 = map(s, z => z + 1) = x => exists(s, y => y + 1 == x)
by inlining f into definition of map. You can check that:
2 is a member of s2, i.e. s2(2) is exists(s, y => y + 1 == 2) is exists(s, y => y == 1) is true.
0 is not a member of s2, i.e. s2(2) is exists(s, y => y + 1 == 0) is exists(s, y => y == -1) is false.
Thinking a bit more, you should be able to list all members of s2, and then to generalize to any s and f.