functional java: what's this P1 thing? - java

I'm looking at Functional Java and I don't understand what a P1 is. Could anyone explain and/or give an example?
(background: I do know what currying and closures are)

This is taken straight from the Google Code project for Functional Java:
Joint union types (tuples) are products of other types. Products of arities 1-8 are provided (fj.P1 - fj.P8). These are useful for when you want to return more than one value from a function, or when you want to accept several values when implementing an interface method that accepts only one argument. They can also be used to get products over other datatypes, such as lists (zip function).
// Regular Java
public Integer albuquerqueToLA(Map<String, Map<String, Integer>> map) {
Map m = map.get("Albuquerque");
if (m != null)
return m.get("Los Angeles"); // May return null.
}
// Functional Java with product and option types.
public Option<Integer> albuquerqueToLA(TreeMap<P2<String, String>, Integer>() map) {
return m.get(p("Albuquerque", "Los Angeles"));
}

P1 looks like the 1-element, trivial product type. In Haskell it would be written as:
data P1 a = P1 a
(the Identity type in Haskell).
that is, it is a container that holds some other type a.
This type also implements the simplest monad, Identity, which allows for functions to be opaquely applied to the contents of the box.
Computationally, there is no reason to use the Identity monad instead of the much simpler act of simply applying functions to their arguments, however, it can be useful in the design of monad transformer stacks.
The monad implementation of the identity monad is trivial,
return a = P1 a
(P1 m) >>= k = k m
As you can see, this is just function application.

aha, found this post:
>>> Also, P1 is potentially lazy. We use it for the implementation of
>>> Stream, for example.
So instead of returning type T directly, I can have something that returns P1<T>, much like Google Collections Supplier<T>, and have it compute the contained value only when P1._1() is called.
(huh, this blog post Lazy Error Handling in Java was interesting too.....)

Related

Utility to merge multiple collections into single collection of same instance type

Want to write an efficient and client friendly way to merge multiple immutable collections into single collection of same instance type
Something like
public static <K> Collection<K> merge(Collection<K>... collection) {
// return merged collection
}
For this, along with the set of collections clients would also need to pass either the instance type of merged collection (in which case I would need to validate compatibility with the set of collections). I don't want to go this route
Is there any way I can infer the type of collection and validate all collections are of the same type and create a new instance of the same type ? Or is this not a valid use case for a general purpose merge implementation and its better off to just provide individual merge implementations for each type ?
This is not easy and requires knowing beforehand an explicit list of types you support. This gets complicated even further by the fact that the immutable types returned by e.g. java.util.List.of(a, b) aren't public types, and their fully qualified type name is not part of the spec (meaning: It could change in a next release of java and that would not be considered a backwards compatibility break; therefore if you rely on the name, your code has a high maintenance burden).
A better idea is perhaps to allow any type of collections, and even a heterogenous list of collections (toss a set, a guava ImmutableList, and a List.of() at it, and a Collections.singleton - your code doesn't care and will merge them all), and have various methods that each return a specifically desired kind of collection.
For example:
import com.google.common.collect.ImmutableList;
public static <K> ImmutableList<K> mergeToList(Collection<K>... collections) {
var out = ImmutableList.<K>builder();
for (Collection<K> c : collections) out.addAll(c);
return out.build();
}
The alternative would be something quite ugly, such as:
import com.google.common.collect.ImmutableList;
public static <K, C extends Collection<K>> C merge(C... collections) {
if (collections.length == 0) throw new IllegalArgumentException("So many problems; one of them is that it becomes impossible to merge zero collections");
Class<?> type = collections[0].getClass();
for (C c : collections) if (c.getClass() != type) throw new IllegalArgumentException("Only pass one kind of collection");
if (type == ImmutableList.class) {
// specific code to merge immutable lists.
} else if (type == Collections.singleton("dummy").getClass()) {
// specific code to merge j.u.Collections singletons.
} else if (type == List.of().getClass()) {
// this becomes virtually impossible; List.of()'s returned type depends on the number of args...
} else {
throw new IllegalArgumentException("Unsupported type: " + type);
}
}
Hopefully that makes clear why you really can't do this. A final option is to have a merge method that takes as parameter a type to merge into, but there is no way to know how to MAKE a collection type. Given com.google.common.collect.ImmutableList, without hardcoding into your source code how to do it, how would you know how to construct a new one?
This is why factories exist in java, and you need one here. collections don't ship with them, so you'd have to explicitly write them for each type you want to support.

Using interfaces instead of concrete data structures in Java Collection API

I am currently reading "Core Java for the Impatient" by Horstmann (I recommend it, love the concise style) and I have a trouble understanding one of the exercises pertaining to the collection API. The exercise is as follows:
I encouraged you to use interfaces instead of concrete data structures, for example, a
Map instead of a TreeMap. Unfortunately, that advice goes only so far. Why can’t
you use a Map<String, Set<Integer>> to represent a table of contents?
(Hint: How would you initialize it?) What type can you use instead?
The following code compiles and works without a problem though, even though the interfaces were used for variable declarations. What am I missing?
Map<String, Set<Integer>> toc = new HashMap<>();
toc.put("element1", IntStream.of(1, 2, 3).boxed().collect(Collectors.toSet()));
toc.put("element2", IntStream.of (3, 4, 7).boxed().collect(Collectors.toSet()));
toc.forEach( (k, v) -> {
System.out.print(k + " ");
v.forEach(val -> System.out.print(val + " "));
System.out.println();
} );
}
An interface like Map is a supertype for all interfaces that inherit it and all classes that implement it. So TreeMap inherits from Map, and because you can always assign to a variable any reference that is of a subtype, it's perfectly acceptable to assign a TreeMap reference to a Map variable. This is called a widening reference conversion
https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.5
"Widening reference conversions never require a special action at run time and therefore never throw an exception at run time. They consist simply in regarding a reference as having some other type in a manner that can be proved correct at compile time."
So, yes, you certainly can use a Map<String, Set<Integer>> to represent something in your domain model, but you can't instantiate an interface directly; you must instantiate a concrete type (class) that implements it. This is exactly what you did when you declared
Map<String, Set<Integer>> toc = new HashMap<>();
As an extension of this principle, you could just as easily write
AbstractMap<String, Set<Integer>> toc = new HashMap<>();
since AbstractMap is also a supertype of HashMap.
In general you want to declare the widest type for the variable that can hold the largest possible set of subtype references that work in your logic. If you need a sorted map, then 'Map' is too wide; it doesn't enforce sortedness. You'd have to declare the variable as TreeMap , or better, SortedMap for that.
Usually the interface is the widest applicable type, but you have to think about it in case it's not.
EDIT: Mentioned SortedMap in light of comment.
I have got in touch with book's author and he agreed that question was unclear and it was to lead the reader to use wildcard types. The exercise in question was changed to:
Suppose you have a method parameter of type Map<String, Set<Integer>>, and someone calls your method with a HashMap<String, HashSet<Integer>>. What happens? What parameter type can you use instead?
The answer is that in this case one should use the wildcard type: Map<String, ? extends Set<Integer>>.

How to add parameters configuration of new operator with rapidminer?

After creating a new operator and testing it, I need to set some configuration such as the definition of minsupp for frequent itemsets algorithms. Actually, I am defining this parameter inside my java code. I like the minsup parameter be viewed in the parameter list when I select the new operator in the Rapidminer GUI.
If I understand you correctly, you want to add parameters to the operator, which are displayed in the GUI.
For that, you have to implement the function getParameterTypes() of your operator. You can get examples about the usage in almost every other operator. An operator with a lot of different parameters that can serve as a good reference is e.g. the k-Means operator, implemented in the class KMeans.
The basic concept is to add instances of ParameterType to a list and returning that list. The RapidMiner framework will do the rest.
The solution is to add instances of PArameterType to a list and returning that list. following is an example:
#Override
public List<ParameterType> getParameterTypes() {
List<ParameterType> types = super.getParameterTypes();
types.add(new ParameterTypeDouble(MinSupp, "Defines the the minimum frequence of an Itemset", 0.0, 1.0));
types.addAll(RandomGenerator.getRandomGeneratorParameters(this));
return types;
}
and Thanks Marius,

Should return statements use generics in Java?

I have a basic question about using the "Best Practices" in coding. (I'm using Java, but the question is general to OOP.) When writing method's for a class that are intended to be used in the long run, is it best to leave the return object with or without generics?
To be specific in my case, I'm returning a Map<String, Integer> with the method. Should I specify this in the return statement, or should I simply return a Map?
It is best to use generics whenever possible. It will help avoid runtime exceptions, and it won't force the people using your code to do a bunch of ugly type casting. For example, if you use the following signature:
Map<String, Integer> getMap();
... then the consuming code might look like this:
Map<String, Integer> map = getMap();
Integer val = map.get(key);
... but if you use a signature like this:
Map getMap();
... the consuming code might look like this:
Map<String, Integer> map = (Map<String, Integer)getMap();
Integer val = map.get(key);
By using generics, not only do you save that (Map<String, Integer>) cast, but in the event that you change getMap to actually return a Map<String, Object>, you will get a compile-time error (which is easy to catch and fix), rather than possibly getting an exception when you call map.get(key) and the JRE tries to do an automatic cast of some random Object into an Integer.
You should definitely return a Map<String, Integer> instead of a plain Map if it makes sense in your method, as this will make it easier for others to use said method - after getting the Map<String, Integer> they will be able to retrieve String keys and Integer values without having to cast them from a generic Object every time (this also makes it a little more typesafe as this way they will know what the keys and values are without even reading the javadoc for your method).
So in short, definitely, return generics.
If you are returning a collection, you should include the generic type that is contained by the collection. For example:
public Map<String, Blammo> getBlammoMap(...)
is (IMHO) preferred to
public Map getBlammoMap(...)
Because it
Limits the options of a bad cast (i.e. kapowMap = (Map<String, Kapow> getBlammoMap()).
Tells the consumer what the method is actually returning.
If the method is clearly intended to work with a certain type (i.e. only String), then it's ok to return a List<String>. If the method is generic taking a type parameter T, you can return List<T>.
I would not simply return a Map, because usually it causes confusion and more boiler-plate code to convert to the desired type.
In general, your type parameters, both input and output, should capture the level of specificity of the precise function. In functional programming, they go so far as to say "the types are the documentation." If I were to see Map foo(Arg args) I would think that foo is in no way concerned with the types in the Map it returns, but somehow relies on Args for something." If I were to see Map<T,String> foo(T t, Arg arg) or Map<T, U> foo(T t, U u) I would think "OK, foo produces a Map based on the type of its t and with a String produced by Arg (or by the U from u)."
In terms of preference, clearly you want to be as clear as possible to the future programmer (yourself or others). Just as returning Map without type-params is obscure, so too would returning Map<String, Integer> might be overly restrictive (and thus misleading) if your foo would work equally well with, say, Map<String, Long>
I believe that more specific, the better. If your method is return a map that always has Strings as the key, and Integers as the value, then definitely use the Map has the return type. That way, any calling code knows exactly what they're getting. If the return type was just Map, then the calling code would have no idea what the class the keys and values are (Other than Object).
In general, you should probably always specify paramerize Maps, Lists, etc., so it's known exactly what it contains. This is very helpful when iterating over them and you can use a java foreach.
for (String currKey : myMap.keySet())
{
System.out.println("curr Key: " + currKey + " curr Value: " + myMap.get(currKey));
}
This eliminates any extra iterators or casting.
Ho-ho-ho! A pretty New Year question.
You generally must (MUST) return a proper generic Map<Whatever, YouNeed>. It may sound crazy, but as soon as you use any generic type without type parameters, you're getting into trouble.
The trouble will be as follows: raw types, being used in the code, change the way methods (even seemingly non-related ones) are resolved. Find a presentation by Joshua Bloch and Bill Pugh called "Java Puzzlers: Scraping the Bottom of the Barrel" for details whle I'm preparing an example :) The video with details is at http://www.parleys.com/#id=2168&st=5 (you may want to scroll to slide 44, 5. "Glommer Pile")
So here's an example:
/**
* (c) (as far as I know) Joshua Bloch and Bill Pugh, 2010
*/
public class Glommer<T> {
String glom(Collection<?> objs) {
String result = "";
for (Object o : objs) result += o;
return result;
}
int glom(List<Integer> ints) {
int result = 0;
for (int i : ints) result += i;
return result;
}
public static void main(String args[]) {
List<String> strings = Arrays.asList("1", "2", "3");
System.out.println(new Glommer().glom(strings));
}
}
Question is, whether it
prints 6
prints 123
throws an exception,
or does something else.
Try to guess. Then compile (yes it compiles) and see what happens.
Now that does not apply to your case. But having a habit of always specifying the type, even if it will be just Map<?,?>, is extremely helpful. You won't lose.
The obligatory Java Generics FAQ link

Generic data type conversion method

This question is in response to another question by opensas: building a generic initializer function in java
From his question it became clear that he needs to convert from any data type T1 to another type T2. When I say "data type" here, I mean types limited to those commonly used to represent raw data: Integer, String, Date, etc. For the purpose of this question we can consider primitives to be boxed.
I'm wondering if there is any API that supports conversion between types where both the input and output are generalized to a set of supported data types. I had a look at Apache Commons' beanutils.converters package, but there's a separate converter class for each known input. I'm looking for any functionality that implements something like the following signature:
static <IN, OUT> OUT convert(IN value, Class<OUT> targetType);
or else
static <IN, OUT> OUT convert(IN value, OUT defaultValue);
It really wouldn't be too hard to implement this kind of mapping oneself, either using a bunch of else if blocks pointing to the various Commons Converters, or else a Map<Class<?>, Converter> for the same purpose. But I'm wondering if this kind of functionality is supported somewhere.
Also, if this winds up being a duplicate I apologize. I tried finding similar questions and was surprised when I found none matching this situation.
EDIT: so an example of this code in action would be:
Integer i = GenericConverter.convert("123", Integer.class); //returns 123
Date d = GenericConverter.convert(1313381772316L, Date.class); //returns today's date
Boolean b = GenericConverter.convert(0, Boolean.class); //returns false
Long l = GenericConverter.convert("asdf", Long.class); //RuntimeException
UPDATE: The BalusC code I linked falls close to the mark, and Bohemian's answer is a nice lightweight solution (although it doesn't work for Boolean conversions). He's also right that Dates should be probably be handled separately if we want to generalize conversion of these other data types. I'm still hoping for additional answers though - especially if there is more of a hands-off API available somewhere.
I am not aware of any library, however the code is just one line.
Apart from Date, all boxed primitives have a String construtor, so this method does the trick:
public static <I, O> O convert(I input, Class<O> outputClass) throws Exception {
return input == null ? null : outputClass.getConstructor(String.class).newInstance(input.toString());
}
To cater for Dates, you could use instanceof within the method, but I would recommend a separate method, since converting dates is a format- and context-sensitive thing (eg String-->Date parses and uses which format?, Long-->Date sets the time).
I have deliberately left error/special handling to the reader as an exercise.
In JDK 8 this can be easily implemented with the new java.util.functions.Mapper interface and a lambda expression.
Mapper<String,Integer> atoi = s -> Integer.valueOf(s);
Integer r = atoi.map("10");
Using method references it can be even simpler:
Mapper<String, Integer> atoi = Integer::new;
Integer r = atoi.map("10");
Or things like:
List<Long> dates = asList(1344754620310L,1344754854877L);
List<Date> asDates = dates.map(Date::new).into(new ArrayList<Date>());
Or cool conversions like:
List<Integer> myInts = "5,4,3,2,1,0,6,7,8,9"
.splitAsStream(",")
.map(Integer::new)
.into(new ArrayList<Integer>());
In the current implementation of the JDK8 API, a few default mappers have been defined (i.e. LongMapper, IntMapper, DoubleMapper) and there's a utility class called Mappers that defines some others like a string mapper, and identity mapper, a constant mapper, etc.
I am not sure if this is what you are after, but certainly it must be a nice way to implement it.
Cases like the one you suggest for:
static <IN, OUT> OUT convert(IN value, Class<OUT> targetType);
Can be implemented with the Mappers utility class:
Mapper<String, Integer> atoi = Mappers.instantiate(String.class, Integer.class);
Integer r = atoi.map("10");
And your signature:
static <IN, OUT> OUT convert(IN value, OUT default);
Could be implemented with something like:
Mapper<String, Integer> atoi = chain(substitute(null, "0"), Integer::new);
Integer r = atoi.map(null); //produces 0
As such, a code like this...
List<String> data = asList("0", null, "2", null, "4", null, "6");
List<Integer> myInts = data.map(chain(substitute(null, "0"), Integer::new)).into(new ArrayList<Integer>());
System.out.println(myInts);
Would yield: [0, 0, 2, 0, 4, 0, 6]
If you are using Spring Framework (spring-core), you can use class
org.springframework.core.convert.support.DefaultConversionService
Default constructor adds many types converter and you can add your own by implementing Converter interface and call addConverter(Converter). There is also nice unit test showing some conversion combinations.
I found something by BalusC that looks close to what I'm asking for: http://balusc.blogspot.com/2007/08/generic-object-converter.html
Unfortunately nothing involving Date conversion is supported, but as the comments indicate, more conversion methods are easily added. His class is essentially a nice little framework that uses reflection to gather up all conversion methods at runtime and put them in a HashMap<String, Method> where the key String is a unique id for that input-output combination.
Still looking for other suggestions! Particularly for an API that would be more hands off than this code I linked to.
Take a look at Variance, which allows you to set up a type conversion context with various converters registered and then move values into and out of a Variant type with type conversion handled by the context.
Variant aVariant = Variant.of("1.2345");
double aDouble = aVariant.doubleValue();
int anInt = Variant.of("12").intValue();
String aString = Variant.of(12.0).toString();
Date aDate = Variant.of("2012-04-06").as(Date.class);
String anIsoFormattedDate = Variant.of(aDate).in(isoDateFormattingContext).toString()
Converters are just Guava Functions from one type to another, and you can register your own, overriding existing conversions where desired.

Categories