How to represent mixins with TypeScript - mixins

I am writing a custom mixin routine, it accepts varags of objects:
type HasIndex = {[key:string]:any};
// type RetType = ?
const mixinAll = (...v: HasIndex[]): RetType => {
return v.reduce((a,b) => doMixing(a,b,new Set()), {});
});
so my question is - how can I represent the return value for mixinAll? Is there a way to represent a mixin type with TypeScript? Very similar to doing the same for Object.assign.

If you look at the definition for Object.assign, that pretty much answers the question:
interface ObjectConstructor {
assign<T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W;
}
in short, use the & operator to create an intersection type - unfortunately can't seem to create something finer-grained than that.

Related

Define type from existed function

How can I create the type from existed function in Dart/Flutter?
I know typedef can create custom type, something like:
typedef Custom<T> = int Function(T a, T b)
But if I have a function from the dependency and want to create the type for arguments, how can I do this?
int functionFromDependency(String a, {int b, ComplexType c}) {
// ...
}
// something syntax like `typeof<functionFromDependency>`
void myProcess(typeof<functionFromDependency>? runner) {
(runner ?? functionFromDependency)(
a,
b: b,
c: c
);
}
It is helpful for testing which can inject custom function.
Dart doesn't have something like C++'s decltype that would allow you to statically re-use the type of some other variable.
In the case of a callback argument to a function, I don't think that it would make sense anyway. For example, you could give up static type-checking and do:
void myProcess(Function? runner) {
(runner ?? functionFromDependency)(
a,
b: b,
c: c
);
}
but ultimately myProcess still requires that runner be a function that can takes a single positional argument and that can take named parameters b and c, all with types appropriate for the supplied arguments. You might as well do:
typedef MyProcessCallback = void Function(A a, {B b, C, c});
void myProcess(MyProcessCallback? runner) {
...
}
myProcess should not be trying to conform to its callers; that's backwards. Callers of myProcess should be conforming to myProcess's API instead, which is much easier.

What is the difference between F[A] and A?

For languages like Scala and Haskell, you can construct types using type constructors. What is the right vocabulary for differentiating between all of these parts?
A is a type. F[A] is also a type. Is there language that exists to differentiate the two?
What is A?
What is F[A]?
What is F?
Dunno about in Scala, but in Haskell, the Report does distinguish between two syntactic categories: "types" and "constructors". Constructors are just those types which are single atoms, beginning with an upper case letter, and created by data and newtype declarations. e.g.
data Foo a = Bar
creates a new type constructor Foo (and a new data constructor Bar), and types can be formed by applying Foo to another type. Of course, constructors need not be of higher kind; data Baz = Quux also declares a type constructor named Baz which is not permitted to be applied to any other types.
(But beware: it is common to use "type constructor" to mean "any type-level expression with an arrow kind", so if you are doing some technical writing, you should include some text in your introduction clarifying which of these two meanings you intend to use in the rest of the document.)
So, in your example, we could say Map is a constructor, Char is a constructor, Int is a constructor, Map Char is a type, and Map Char Int is a type.
As far as I know, there is no common shorthand term for any of these categories: "a type which is definitely not a constructor", "a type of kind *", "a type which is definitely not of kind *". For types which are allowed to be applied to another type, there is the term "higher-kinded type" -- e.g. Map and Map Char are both higher-kinded types.
I would propose to just call F[A] application of a type constructor F of kind * -> * to the argument A of kind *. "Type constructor" comes from the specification, whereas "application" comes from the basic lambda calculus, as explained below.
Recall that the formalism of higher-kinded types with all the type constructors is essentially just an extension of a simply typed lambda calculus over a single type *.
That means that you have the following rules for forming kinds:
* is a kind
if a, b are kinds, then a -> b is a kind
You can form terms as follows:
Predefined constants with fixed kind are terms
Variables are terms
If f and a are terms, then the application f a is a term
If x is a variable name, and y is a term, then the abstraction \x.y is a term
You can check whether a (type-valued) term is well-kinded with rules that look somewhat like this:
Predefined constant c of kind k (vacuously) has kind k, regardless of context
If context Gamma contains mapping of a variable v to kind k, then in Gamma we can infer that v is a well-kinded expression of kind k.
If in context Gamma we can infer that f has kind a -> b and x has kind a, then the application f x has kind b.
If in context Gamma, x: a we can infer that y has kind b, then in Gamma we can infer that \x.y has kind a -> b.
I don't see any reason to invent any new vocabulary, so I would just use "application".
An aside: you can actually write down the above basic kind-inference algorithm really quickly.
sealed trait Term
case class Apply(func: Term, arg: Term) extends Term
case class Lam(preferred: String, dom: Type, body: Term) extends Term
case class BoundVar(deBruijnIdx: Int) extends Term
case class FreeVar(name: String) extends Term
sealed trait Type
case object * extends Type
case class Func(dom: Type, cod: Type) extends Type {
override def toString = s"($dom -> $cod)"
}
import util.{Either, Left, Right}
case class Ctx(globalConstants: Map[String, Type], stack: List[Type]) {
def push(tp: Type): Ctx = Ctx(globalConstants, tp :: stack)
def pop: Ctx = Ctx(globalConstants, stack.tail)
}
object Ctx {
def empty = Ctx(Map.empty, List.empty)
def emptyWithGlobals(keys: (String, Type)*) = Ctx(keys.toMap, Nil)
}
def tinf(t: Term, ctx: Ctx = Ctx.empty): Either[String, Type] = t match {
case FreeVar(v) =>
ctx.globalConstants.get(v).map(Right(_)).getOrElse(Left("Undefined: " + v))
case BoundVar(d) => Right(ctx.stack(d))
case Apply(f, x) =>
for {
tf <- tinf(f, ctx)
tx <- tinf(x, ctx)
res <- tf match {
case Func(a, b) =>
if (tx == a) Right(b)
else Left(s"Type mismatch: cannot apply `$a` to `$b`")
case sthElse => Left(s"Not applicable: $sthElse")
}
} yield res
case Lam(_, tp, b) =>
for {
tb <- tinf(b, ctx.push(tp))
} yield Func(tp, tb)
}
for {
example <- List(
Lam("x", *, BoundVar(0)),
Lam("x", *, Lam("y", Func(*, *), Apply(BoundVar(0), BoundVar(1))))
)
} println(example + " : " + tinf(example))
and it will happily infer that type-lambdas
\(x:*).x
\(x:*).\y(* -> *). y x
have the kinds
(* -> *)
(* -> ((* -> *) -> *))
respectively.
The technical terms, as mentioned in the comments, are 'type', 'some other type', and a 'type constructor'.
Consider:
data A = A
-- ^ ^--- The Data Constructor
-- -- The type
data F x = SomeDataConstructorForF x
-- ^ ^ ^-- Data Constr ^-- Field
-- | --- Type Variable
-- - Type Constructor
val :: A
val = A
-- A value of type 'A'
val2 :: F [A]
val2 = SomeDataConstructorForF []
-- A value of some other type, F [A].
-- No special term exists for types built through application
-- of one or more type constructor afaik

Scala - Make signature of function parameter f of higher order function g dependent on varars of g

I am trying to define a higher order function f which accepts a variable number of parameters args of type Wrapper[T]* and a function parameter g in Scala.
The function f should decapsulate each object passed in args and then call g with the decapsulated parameters. Therefore, g has to accept exactly the same number of parameters of type T as args contains.
The closest thing I could achieve was to pass a Seq[T] to g and to use pattern matching inside of g. Like the following:
f("This", "Is", "An", "Example")(x => x match {
case Seq(a:String, b:String, c:String): //Do something.
})
With f defined like:
def f[V](args: Wrapper[T]*)
(g: (Seq[T]) => (V)) : V = {
val params = args.map(x => x.unwrap())
g(params)
}
How is it possible to accomplish a thing like this without pattern
matching?
It is possible to omit the types in the signature of g
by using type inference, but only if the number of parameters is
fixed. How could this be done in this case?
It is possible to pass
different types of parameters into varargs, if a type wildcard is
used args: Wrapper[_]*. Additionally, casting the result of
x.unwrap to AnyRef and using pattern matching in g is
necessary. This, however, completely breaks type inference and type
safety. Is there a better way to make mixing types in the varargs
possible in this special case?
I am also considering the use of scala makros to accomplish these tasks.
Did I get you right? I replaced your Wrapper with some known type, but that doesn't seem to be essential.
def f[T, V](args: T*)(g: PartialFunction[Seq[T], V]): V = g(args)
So later you can do this:
f(1,2,3) { case Seq(a,b,c) => c } // Int = 3
Okay, I've made my own Wrapper to be totally clear:
case class Wrapper[T](val x:T) {
def unwrap = x
}
def f[V](args: Wrapper[_]*)(g: PartialFunction[Seq[_], V]): V =
g(args.map(_.unwrap))
f(Wrapper("1"), Wrapper(1), Wrapper(BigInt(1))) {
case Seq(s: String, i: Int, b: BigInt) => (s, i, b)
} // res3: (String, Int, BigInt) = (1,1,1)
Regarding your concerns about type safety and conversions: as you can see, there aren't any explicit conversions in the code above, and since you are going to pattern-match with explicitly defined types, you may not to worry about these things - if some items of an undefined origin are going to show in your input, scala.MatchError will be thrown.

What's the difference between multiple parameters lists and multiple parameters per list in Scala?

In Scala one can write (curried?) functions like this
def curriedFunc(arg1: Int) (arg2: String) = { ... }
What is the difference between the above curriedFunc function definition with two parameters lists and functions with multiple parameters in a single parameter list:
def curriedFunc(arg1: Int, arg2: String) = { ... }
From a mathematical point of view this is (curriedFunc(x))(y) and curriedFunc(x,y) but I can write def sum(x) (y) = x + y and the same will be def sum2(x, y) = x + y
I know only one difference - this is partially applied functions. But both ways are equivalent for me.
Are there any other differences?
Strictly speaking, this is not a curried function, but a method with multiple argument lists, although admittedly it looks like a function.
As you said, the multiple arguments lists allow the method to be used in the place of a partially applied function. (Sorry for the generally silly examples I use)
object NonCurr {
def tabulate[A](n: Int, fun: Int => A) = IndexedSeq.tabulate(n)(fun)
}
NonCurr.tabulate[Double](10, _) // not possible
val x = IndexedSeq.tabulate[Double](10) _ // possible. x is Function1 now
x(math.exp(_)) // complete the application
Another benefit is that you can use curly braces instead of parenthesis which looks nice if the second argument list consists of a single function, or thunk. E.g.
NonCurr.tabulate(10, { i => val j = util.Random.nextInt(i + 1); i - i % 2 })
versus
IndexedSeq.tabulate(10) { i =>
val j = util.Random.nextInt(i + 1)
i - i % 2
}
Or for the thunk:
IndexedSeq.fill(10) {
println("debug: operating the random number generator")
util.Random.nextInt(99)
}
Another advantage is, you can refer to arguments of a previous argument list for defining default argument values (although you could also say it's a disadvantage that you cannot do that in single list :)
// again I'm not very creative with the example, so forgive me
def doSomething(f: java.io.File)(modDate: Long = f.lastModified) = ???
Finally, there are three other application in an answer to related post Why does Scala provide both multiple parameters lists and multiple parameters per list? . I will just copy them here, but the credit goes to Knut Arne Vedaa, Kevin Wright, and extempore.
First: you can have multiple var args:
def foo(as: Int*)(bs: Int*)(cs: Int*) = as.sum * bs.sum * cs.sum
...which would not be possible in a single argument list.
Second, it aids the type inference:
def foo[T](a: T, b: T)(op: (T,T) => T) = op(a, b)
foo(1, 2){_ + _} // compiler can infer the type of the op function
def foo2[T](a: T, b: T, op: (T,T) => T) = op(a, b)
foo2(1, 2, _ + _) // compiler too stupid, unfortunately
And last, this is the only way you can have implicit and non implicit args, as implicit is a modifier for a whole argument list:
def gaga [A](x: A)(implicit mf: Manifest[A]) = ??? // ok
def gaga2[A](x: A, implicit mf: Manifest[A]) = ??? // not possible
There's another difference that was not covered by 0__'s excellent answer: default parameters. A parameter from one parameter list can be used when computing the default in another parameter list, but not in the same one.
For example:
def f(x: Int, y: Int = x * 2) = x + y // not valid
def g(x: Int)(y: Int = x * 2) = x + y // valid
That's the whole point, is that the curried and uncurried forms are equivalent! As others have pointed out, one or the other form can be syntactically more convenient to work with depending on the situation, and that is the only reason to prefer one over the other.
It's important to understand that even if Scala didn't have special syntax for declaring curried functions, you could still construct them; this is just a mathematical inevitability once you have the ability to create functions which return functions.
To demonstrate this, imagine that the def foo(a)(b)(c) = {...} syntax didn't exist. Then you could still achieve the exact same thing like so: def foo(a) = (b) => (c) => {...}.
Like many features in Scala, this is just a syntactic convenience for doing something that would be possible anyway, but with slightly more verbosity.
The two forms are isomorphic. The main difference is that curried functions are easier to apply partially, while non-curried functions have slightly nicer syntax, at least in Scala.

Can Scala allow free Type Parameters in arguments (are Scala Type Parameters first class citizens?)?

I have some Scala code that does something nifty with two different versions of a type-parameterized function. I have simplified this down a lot from my application but in the end my code full of calls of the form w(f[Int],f[Double]) where w() is my magic method. I would love to have a more magic method like z(f) = w(f[Int],f[Double]) - but I can't get any syntax like z(f[Z]:Z->Z) to work as it looks (to me) like function arguments can not have their own type parameters. Here is the problem as a Scala code snippet.
Any ideas? A macro could do it, but I don't think those are part of Scala.
object TypeExample {
def main(args: Array[String]):Unit = {
def f[X](x:X):X = x // parameterize fn
def v(f:Int=>Int):Unit = { } // function that operates on an Int to Int function
v(f) // applied, types correct
v(f[Int]) // appplied, types correct
def w[Z](f:Z=>Z,g:Double=>Double):Unit = {} // function that operates on two functions
w(f[Int],f[Double]) // works
// want something like this: def z[Z](f[Z]:Z=>Z) = w(f[Int],f[Double])
// a type parameterized function that takes a single type-parameterized function as an
// argument and then speicalizes the the argument-function to two different types,
// i.e. a single-argument version of w() (or wrapper)
}
}
You can do it like this:
trait Forall {
def f[Z] : Z=>Z
}
def z(u : Forall) = w(u.f[Int], u.f[Double])
Or using structural types:
def z(u : {def f[Z] : Z=>Z}) = w(u.f[Int], u.f[Double])
But this will be slower than the first version, since it uses reflection.
EDIT: This is how you use the second version:
scala> object f1 {def f[Z] : Z=>Z = x => x}
defined module f1
scala> def z(u : {def f[Z] : Z=>Z}) = (u.f[Int](0), u.f[Double](0.0))
z: (AnyRef{def f[Z]: (Z) => Z})(Int, Double)
scala> z(f1)
res0: (Int, Double) = (0,0.0)
For the first version add f1 extends Forall or simply
scala> z(new Forall{def f[Z] : Z=>Z = x => x})
If you're curious, what you're talking about here is called "rank-k polymorphism." See wikipedia. In your case, k = 2. Some translating:
When you write
f[X](x : X) : X = ...
then you're saying that f has type "forall X.X -> X"
What you want for z is type "(forall Z.Z -> Z) -> Unit". That extra pair of parenthesis is a big difference. In terms of the wikipedia article it puts the forall qualifier before 2 arrows instead of just 1. The type variable can't be instantiated just once and carried through, it potentially has to be instantiated to many different types. (Here "instantiation" doesn't mean object construction, it means assigning a type to a type variable for type checking).
As alexy_r's answer shows this is encodable in Scala using objects rather than straight function types, essentially using classes/traits as the parens. Although he seems to have left you hanging a bit in terms of plugging it into your original code, so here it is:
// this is your code
object TypeExample {
def main(args: Array[String]):Unit = {
def f[X](x:X):X = x // parameterize fn
def v(f:Int=>Int):Unit = { } // function that operates on an Int to Int function
v(f) // applied, types correct
v(f[Int]) // appplied, types correct
def w[Z](f:Z=>Z,g:Double=>Double):Unit = {} // function that operates on two functions
w(f[Int],f[Double]) // works
// This is new code
trait ForAll {
def g[X](x : X) : X
}
def z(forall : ForAll) = w(forall.g[Int], forall.g[Double])
z(new ForAll{def g[X](x : X) = f(x)})
}
}
I don't think what you want to do is possible.
Edit:
My previous version was flawed. This does work:
scala> def z(f: Int => Int, g: Double => Double) = w(f, g)
z: (f: (Int) => Int,g: (Double) => Double)Unit
scala> z(f, f)
But, of course, it is pretty much what you have.
I do not think it is even possible for it to work, because type parameters exist only at compile-time. At run time there is no such thing. So it doesn't make even sense to me to pass a parameterized function, instead of a function with the type parameters inferred by Scala.
And, no, Scala has no macro system.