Haskell中一些特殊的类型类。
Functor
有些类型是代表计算上下文,比如Maybe的上下文是可能有值或没有值,对其中的值并不太关心,但我们还需要对Maybe中的值进行计算并保持这种上下文,也就是说如果有值就进行某种计算,如果没有值就继续没有值。这种能够保持上下文并继续计算的类型就是Functor。在Haskell中用类型类Functor表示
class Functor f where
fmap :: (a -> b) -> f a -> fb
用Java的接口表示
interface Functor<A, F extends Functor<?, ?>> {
<B> F fmap(Function<A, B> func);
}
Java的类型参数不能像Haskell那样是类型构造器,所以fmap的返回值无法定义成F<B>类型。不过可以在Functor的具体实现类中声明具体的返回类型,比如Maybe的实现,详细代码请参考这里 。
class Maybe<A> implements Functor<A, Maybe<?>> {
<B> Maybe<B> fmap(Function<A, B> func) {
}
}
这种Java实现只能表达函数调用,给人的感觉是fmap就是一个以函数为参数的函数,不能体现fmap函数的lifting特性(看一下Haskell的定义再结合柯里化的理解,不难发现,fmap的输入是普通函数a->b,返回是新的函数f a -> f b)。更能体现lifting特性的Java定义如下,详细代码请参考这里 和这里 :
interface Functor2<A> {
<B> Functor2<B> apply(Function<A, B> fn);
static <A, B> Function<Functor2<A>, Functor2<B>> fmap(Function<A, B> fn) {
return fa -> fa.apply(fn);
}
在学习Haskell概念时参考了在线版本的learn you a Haskell 。
在实现Java的Functor接口时参考了文章Functors in Java 。