Free monad interpreter with side effect only - scala-cats

I need to write free monad interpreter which only perform effectfull actions but does not return any result. For free applicative I used interpreter with MyAction ~> Const[Unit, ?] signature and called it using foldMap function. However Const does not have monad instance. Id does not suit because it requires to return actual value (evaluate embedded language). Should I write my own monad instance, similar to Id but without underlying value or there is a more convient way to create interpreter which does not produce any values?

What do you mean by "not producing any value"? Here is Free monad example with interpreters that return nothing, but do something.
import cats.{Id, ~>}
import cats.effect.{ExitCode, IO, IOApp}
import cats.free.Free
import cats.free.Free.liftF
object Main extends IOApp {
// define algebra
sealed trait LaunchMissilesA[A]
case class LaunchMissileType1(arg: Int) extends LaunchMissilesA[Unit]
case class LaunchMissileType2(arg: String) extends LaunchMissilesA[Unit]
// define Free type
type LaunchMissiles[A] = Free[LaunchMissilesA, A]
// smart constructors
def launchMissileType1(arg: Int): LaunchMissiles[Unit] = liftF[LaunchMissilesA, Unit](LaunchMissileType1(arg))
def launchMissileType2(arg: String): LaunchMissiles[Unit] = liftF[LaunchMissilesA, Unit](LaunchMissileType2(arg))
// final program
def launchVariousMissiles: LaunchMissiles[Unit] =
for {
_ <- launchMissileType1(1)
_ <- launchMissileType2("str2")
} yield ()
// interpreter #1: IO
def ioMissileLauncher: LaunchMissilesA ~> IO = new (LaunchMissilesA ~> IO) {
override def apply[A](fa: LaunchMissilesA[A]): IO[A] = fa match {
case LaunchMissileType1(arg) =>
IO(println(s"[IO] launching Int missile of type 1: $arg").asInstanceOf[A])
case LaunchMissileType2(arg) =>
IO(println(s"[IO] launching String missile of type 2: $arg").asInstanceOf[A])
}
}
// interpreter #2: Id
def idMissileLauncher: LaunchMissilesA ~> Id = new (LaunchMissilesA ~> Id) {
override def apply[A](fa: LaunchMissilesA[A]): Id[A] = fa match {
case LaunchMissileType1(arg) =>
println(s"[Id] launching Int missile of type 1: $arg").asInstanceOf[A]
case LaunchMissileType2(arg) =>
println(s"[Id] launching String missile of type 2: $arg").asInstanceOf[A]
}
}
// end of the world
override def run(args: List[String]): IO[ExitCode] = for {
_ <- launchVariousMissiles.foldMap(ioMissileLauncher)
_ <- IO(launchVariousMissiles.foldMap(idMissileLauncher))
} yield ExitCode(0)
}

Related

TypeScript: Catch variable signature of a function passed as argument in higher order function

I would like for a higher order function to be able to catch the signature parameters of the passed function which can have different signature.
I don't know if it's feasible but this was my approach to it :
type FuncA = (a: string, b: number) => void
type FuncB = (a: string) => void
type Func = FuncA | FuncB
const a: FuncA = (a: string, b: number) => {
console.log('FuncA')
}
const b: FuncB = (a: string) => {
console.log('FuncB')
}
// My higher order function
const c = (func: Func) => {
// do something here...
return (...args: Parameters<typeof func>) => {
func(...args) // Expected 2 arguments, but got 0 or more. ts(2556). An argument for 'a' was not provided.
}
}
My higher order function c couldn't pass the parameters of func
It seems like TypeScript cannot discriminate the different possible signature of type Func.
Does anyone know a pattern to write this kind of code?
Thank you !
This is a tough one because for a function to extend another function doesn't mean quite what you think.
We want the function created by c to require that arguments correspond to the function that it was given. So we use a generic to describe the function.
const c = <F extends Func>(func: F) => {
return (...args: Parameters<F>) => {
func(...args); // still has error
}
}
At this point we still have that error, but when we call c, we get a function which has the right arguments based on whether we gave it a or b.
const cA = c(a); // type: (a: string, b: number) => void
cA("", 0);
const cB = c(b); // type: (a: string) => void
cB("");
As for the error, it has to do with what it means for a function to extend another function. Try changing F extends Func to F extends FuncA and F extends FuncB to see what happens. With F extends FuncB we get an error on c(a), but with F extends FuncA we don't get an error on c(b). Huh?
If you think about it in terms of a callback it makes sense. It's ok to pass a function that requires less arguments than expected, but not ok to pass one that requires more. But we are the ones implementing the callback so this creates a problem for us. If we extend type Func with a function that has no arguments, the empty array from Parameters<F> isn't sufficient to call either type.
We have to make our generic depend on the arguments instead.
type AP = Parameters<FuncA> // type: [a: string, b: number]
type BP = Parameters<FuncB> // type: [a: string]
type Args = AP | BP;
const c = <A extends Args>(func: (...args: A) => void) => {
return (...args: A) => {
func(...args) // no error
}
}
Typescript Playground Link
If you're ok with the decorated function being any function, you could do:
const c = <T extends (...a: any) => any>(func: T) => {
// do something here...
return (...args: Parameters<typeof func>): ReturnType<T> => {
return func(...args);
}
}
Calling it would look like
c<typeof a>(a)('a', 2)

Haskell type classes

How haskell types are different than regular PHP classes.
If i disable extending can I simulate something similar in PHP or JavaScript.
Haskell:
data Person = Person { firstName :: String
, lastName :: String
, age :: Int
, height :: Float
, phoneNumber :: String
, flavor :: String
age :: Person -> Int
age (Person p) = p.age
newAge = age(Person {age:=35})
Js:
class Person {
constructor(data) {
this.data = data
}
}
function age(p) {
if (p instanceof Person) return p.age
}
let personAge = age(new Person({age: 35})); // 35
There can be syntax errors but ignore them.
In a nutshell if I dont use inheritance the js code is similar to Haskell's.
I dont have pattern matching but i can use "if instanceof " to check types.
Besides the confusion between type classes and data types, you may want to read OOP vs. Haskell type classes. Data types, which you use, behave much like immutable objects. So Haskell's
data Person = Person { age :: Int }
p1, p2 :: Person
p1 = Person { age = 35 }
p2 = p1 { age = age p1 + 1 }
might be written in ES6 like
class Person {
constructor(age) {
this.age = age;
}
}
p1 = new Person(35);
p2 = new Person(p1.age + 1);
In ES6 this does not guarantee against immutability, though. For that, see the const and ... keywords for merging the properties of objects without changing the original objects. The article discusses various other solutions but ends up suggesting:
const p1 = {
age: 35
}
const p2 = {
...p1,
age: p1.age + 1
}

Idiomatic means of choosing class constructor in groovy

I have a class like this:
in foo.groovy
class Foo {
String thing
Integer other
Foo(String thing) {
this.thing = thing
}
Foo(Integer other) {
this.other = other
}
}
return Foo.class
Now I would like to invoke these constructors. What I am doing is:
Other.groovy
def foo = evaluate(new File(ClassLoader.getSystemResource('foo.groovy').file)).newInstance(10)
def foo2 = evaluate(new File(ClassLoader.getSystemResource('foo.groovy').file)).newInstance("thing")
But this doesn't seem like the correct way of doing it. Ideally I would like to actually name the file Foo.groovy but then I get an error because it automatically declares the class for me. Basically, I want it to work like a classic Java class
Maybe I'm missing something here, but:
class Foo {
String thing
Integer other
Foo(String thing) {
this.thing = thing
}
Foo(Integer other) {
this.other = other
}
}
def x = new Foo(10)
assert x.other == 10 // true
def y = new Foo("foo")
assert y​​​​.thing​ == "foo"​​ // true
What are you trying to accomplish here other than that?
Edit: Try it here.

Equals function doesn't work with custom object in spark

I'm haveing trouble, I presume with serialization, in a Spark repl.
I have the following code snippet:
class Foobar (val a: Int, val b: Int) extends Serializable {
override def equals (other: Any): Boolean =
other match {
case that: Foobar =>
println("Comparison of similar objects")
this.a == that.a && this.b == that.b
case _ =>
println("Comparison of disparate objects")
false
}
override def toString = s"[$a:$b]"
}
If I create two instances, one (foo) on a worker, and one (bar) on the driver:
val foo = sc.parallelize(Seq(1)).map(n => new Foobar(n, n)).collect.apply(0)
val bar = new Foobar(1, 1)
then foo != bar (and spouts "Comparison of disparate objects") - yet
foo.getClass == bar.getClass
foo.a == bar.a, and
foo.b == bar.b
Can anyone explain why this happens?

How can a Groovy closure curry itself for repetition?

I'm implementing Groovy step definitions for Cucumber-JVM and I want a step to be able store itself so that the next step can repeat it n times.
Given(~'the (\\S+) is in the blender') { String thing ->
// do stuff...
context.repeatable = self.curry(thing)
}
What should "self" be in the above code?
I can't use "this" as that refers to the enclosing object (whatever that is in this case, maybe the script).
Since curry is a method of the Closure class, directly invoking curry applies to the closure, both if it is named:
def context
test = { String thing ->
context = curry(thing)
thing.toUpperCase()
}
test('hello')
println context.call()
test('world')
println context.call()
=>
HELLO
WORLD
or anonymous:
def context
['test'].each { String thing ->
context = curry(thing)
thing.toUpperCase()
}
println context.call()
=>
TEST
You can try using unreferenced curry method passing the received parameters:
clos = { String text ->
if (text) {
println "text=$text"
a = curry null
a()
} else {
println "done"
}
}
clos "closure text"
Will print:
text=closure text
done
Update
You can also use clone():
closure = {
def clone = clone()
}

Resources