【続】「純粋関数型JavaScriptのつくりかた」に触発されて

続いて、いろいろと試してみた。

```C#:C#
using System;
class Pure{

 public static
 Func<object,Func<object>>
 pure=a=>()=>a;

 public static
 Func<Func<object>,
 Func<Func<object,Func<object>>,
 Func<object>>>
 bind=m=>f=>()=>f(m())();

 public static
 Func<Func<object>,object>
 exec=m=>m();

 public static
 Func<Func<object,object>,
 Func<object,Func<object>>>
 wrap=f=>a=>()=>f(a);
}

class MainClass{
 static void Main(){

   string str="";

   Func<object,Func<object>>
   put=Pure.wrap(a=>{Console.WriteLine(a);
   return a;});

   Func<object,Func<object>>
   get=Pure.wrap(x=>Console.ReadLine());

   Func<int,Func<object,Func<object,
   Func<object,object>>>>
   _hanoi=n=>from=>work=>dest=>null;
   _hanoi=n=>from=>work=>dest=>
   { if(n>=2)_hanoi(n-1)(from)(dest)(work);
     str=str+n.ToString()+" を "
     +from+" から "+dest+" へ\n"; 
     if(n>=2)_hanoi(n-1)(work)(from)(dest);
     return str;
   };

   Func<object,Func<object>>
   hanoi=Pure.wrap(a=>
   _hanoi(int.Parse((string)a))
   ("A")("B")("C"));

   Func<object>
   step1=Pure.bind(get(null))(hanoi);

   Func<object>
   main=Pure.bind(step1)(put);

   Pure.exec(main);

 }
}
```

```Java:Java
import java.io.*;
import java.util.function.*;

class Pure{

 public static
 Function<Object,Supplier<Object>>
 pure=a->()->a;

 public static
 Function<Supplier<Object>,
 Function<Function<Object,
 Supplier<Object>>,
 Supplier<Object>>>
 bind=m->f->()->f.apply(m.get()).get();

 public static
 Function<Supplier<Object>,Object>
 exec=m->m.get();

 public static
 Function<Function<Object,Object>,
 Function<Object,Supplier<Object>>>
 wrap=f->a->()->f.apply(a);
}

class Main{

 static BufferedReader in=new
 BufferedReader(new
 InputStreamReader(System.in));

 static Object _get(){
   Object s=null;
   try{
     s=in.readLine();
   }catch(Exception e){
     e.printStackTrace();
   }
   return s;
 }

 static String str="";

 static Function<Integer,Function<Object,
 Function<Object,Function<Object,Object>>>>
 _hanoi=n->from->work->dest->null;

 public static void main (String[] args){

   Function<Object,Supplier<Object>>
   put=Pure.wrap.apply(a->
   {System.out.println(a);return a;});

   Function<Object,Supplier<Object>>
   get=Pure.wrap.apply(x->_get());
   
   _hanoi=n->from->work->dest->
   { if(n>=2)_hanoi.apply(n-1).
     apply(from).apply(dest).apply(work);
     str=str+Integer.toString(n)+
     " を "+from+" から "+dest+" へ\n";
     if(n>=2)_hanoi.apply(n-1).
     apply(work).apply(from).apply(dest);
     return str;
   };

   Function<Object,Supplier<Object>>
   hanoi=Pure.wrap.apply(a->
   _hanoi.apply(
   Integer.parseInt((String)a))
   .apply("A")
   .apply("B")
   .apply("C"));

   Supplier<Object>
   step1=Pure.bind.apply
   (get.apply(null)).apply(hanoi);

   Supplier<Object>
   main=Pure.bind
   .apply(step1).apply(put);

   Pure.exec.apply(main);

 }
}
```

```Python3:Python3
pure=lambda a:lambda:a
bind=lambda m:lambda f:lambda:f(m())()
exec=lambda m:m()
wrap=lambda f:lambda a:lambda:f(a)

put=wrap(lambda a:print(a))
get=wrap(lambda a:input())

s=""

_hanoi=(lambda n:
lambda f:lambda w:lambda d: 
(_hanoi(n-1)(f)(d)(w)if n>=2else s)
+(str(n)+" を "+f+" から "+d+" へ\n")
+(_hanoi(n-1)(w)(f)(d)if n>=2else s))

hanoi=wrap(lambda a:
_hanoi(int(a))("A")("B")("C"))

step1=bind(get(""))(hanoi)
main=bind(step1)(put)

exec(main)
```