Skip to content

Instantly share code, notes, and snippets.

@keigoi
Last active December 12, 2016 05:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keigoi/7905c866b75755483b6560975b53c9d3 to your computer and use it in GitHub Desktop.
Save keigoi/7905c866b75755483b6560975b53c9d3 to your computer and use it in GitHub Desktop.
An attempt of simple implementation of lens on Java 8
class IxMonad<X,Y,T>(val x:T) {}
class Cons<HD,TL>(val hd : HD, val tl : TL) {}
class Nil();
fun <X,Y,T> ret(x: T) : IxMonad<X,Y,T> {
return IxMonad<X,Y,T>(x)
}
fun <T> run(m : IxMonad<Nil,Nil,T>) : T {
return m.x;
}
abstract class Lens<X,Y,SS,TT>() {
abstract fun get(ss : SS) : X;
abstract fun put(ss : SS, y : Y) : TT;
}
class _0<X,Y,SS>() : Lens<X,Y,Cons<X,SS>,Cons<Y,SS>>() {
override fun get(ss : Cons<X,SS>) : X {
return ss.hd
}
override fun put(ss : Cons<X,SS>, y : Y) : Cons<Y,SS> {
return Cons(y, ss.tl)
}
}
fun <X,Y,SS,TT> put(l : Lens<X,Y,SS,TT>, ss : SS, y : Y) : TT {
return l.put(ss, y)
}
fun main(args: Array<String>) {
run(ret(1))
var ss = Cons(1,Nil());
var msg = put(_0(), ss, "Hello, World!").hd;
println(msg)
}
public class LensTest {
static class Unit {}
// Heterogeneous list constructors
static class Cons<HD, TL> { public Cons(HD hd, TL tl) { this.hd = hd; this.tl =tl; } HD hd; TL tl; }
static class Nil {}
public static final Nil nil = new Nil();
// Parametric lens
static abstract class Lens<A, B, SS, TT> {
abstract public A get(SS ss);
abstract public TT put(SS ss, B b);
}
// lens on the 0th element
public static class __0<A, B, SS> extends Lens<A, B, Cons<A,SS>, Cons<B,SS>> {
@Override public A get(Cons<A,SS> ss) {
return ss.hd;
}
@Override public Cons<B,SS> put(Cons<A,SS> ss, B b) {
return new Cons<B,SS>(b, ss.tl);
}
}
public static <A, B, SS> Lens<A, B, Cons<A,SS>, Cons<B,SS>> _0() {
return new __0<>();
}
// Helper methods
public static <A,B,SS,TT> A lens_get(Lens<A, B, SS, TT> l, SS s) {
return l.get(s);
}
public static <A,B,SS,TT> TT lens_put(Lens<A, B, SS, TT> l, SS s, B b) {
return l.put(s, b);
}
public static void main(String[] args) {
Cons<String, Nil> c1 = new Cons<>("abc", nil);
lens_put(_0(), c1, 123); // OK
int x = lens_put(_0(), c1, 123).hd + 456; // OK
// _0().put(c1, 123); // ERROR
// LensTest.java:42: error: method put in class Lens<A,B,SS,TT> cannot be applied to given types;
// _0().put(c1, 123); // ERROR
// ^
// required: Cons<Object,Object>,Object
// found: Cons<String,Nil>,int
// reason: argument mismatch; Cons<String,Nil> cannot be converted to Cons<Object,Object>
// where A,B,SS,TT are type-variables:
// A extends Object declared in class Lens
// B extends Object declared in class Lens
// SS extends Object declared in class Lens
// TT extends Object declared in class Lens
// 1 error
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
static class Unit { }
// Heterogeneous list constructors
class Cons<HD, TL> { public Cons(HD hd, TL tl) { this.hd = hd; this.tl = tl; } public HD hd; public TL tl; }
class Nil { }
// Parametric lens
abstract class Lens<A, B, SS, TT>
{
abstract public A get(SS ss);
abstract public TT put(SS ss, B b);
}
// lens on the 0th element
class __0<A, B, SS> : Lens<A, B, Cons<A, SS>, Cons<B, SS>> {
override public A get(Cons<A, SS> ss)
{
return ss.hd;
}
override public Cons<B, SS> put(Cons<A, SS> ss, B b)
{
return new Cons<B, SS>(b, ss.tl);
}
}
class Program {
public static Nil nil = new Nil();
public static Lens<A, B, Cons<A, SS>, Cons<B, SS>> _0<A, B, SS>()
{
return new __0<A,B,SS>();
}
// Helper methods
public static A lens_get<A, B, SS, TT>(Lens<A, B, SS, TT> l, SS s)
{
return l.get(s);
}
public static TT lens_put<A, B, SS, TT>(Lens<A, B, SS, TT> l, SS s, B b)
{
return l.put(s, b);
}
static void Main(string[] args)
{
var c1 = new Cons<String, Nil>("abc", nil);
// lens_put(_0(), c1, 123); // NG (csc.exe 4.6.1586.0)
// エラー CS0411 メソッド 'Program._0<A, B, SS>()' の型引数を使い方から推論することはできません。
// 型引数を明示的に指定してください。
}
}
}
class CONS(HD,TL)
getter :hd, :tl
def initialize(@hd : HD, @tl : TL)
end
end
class NIL
end
abstract class Lens(A,B,SS,TT)
abstract def get(ss : SS) : A
abstract def put(ss : SS, b : B) : TT
end
class L0(A,B,SS) < Lens(A,B,CONS(A,SS),CONS(B,SS))
def get(ss)
ss.hd
end
def put(ss, b)
CONS.new(b,ss.tl)
end
end
def _0() : Lens(A,B,Cons(A,SS),Cons(B,SS)) forall A, B, SS
return L0.new()
end
def lens_put(l : Lens(A,B,SS,TT), ss, b) forall A, B, SS, TT
l.put(ss,b)
end
c1 = CONS.new(1, NIL.new())
c2 = CONS.new(1, NIL.new())
p (L0.new().get(c1) + 2) # NG
# Error in Test.cr:36: can't infer the type parameter A for the generic class L0(A, B, SS). Please provide it explicitly
lens_put(L0.new(), c1, "abc") # NG
# Error in Test.cr:39: can't infer the type parameter A for the generic class L0(A, B, SS). Please provide it explicitly
lens_put(L0(Int32,String,NIL).new(), c1, "abc") # OK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment