Last active
December 12, 2016 05:05
-
-
Save keigoi/7905c866b75755483b6560975b53c9d3 to your computer and use it in GitHub Desktop.
An attempt of simple implementation of lens on Java 8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>()' の型引数を使い方から推論することはできません。 | |
// 型引数を明示的に指定してください。 | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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