Advertisement
Guest User

Untitled

a guest
Jul 21st, 2019
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.19 KB | None | 0 0
  1. #![allow(dead_code)]
  2.  
  3. /// so, when are two type, `a` and `b`, considered equal?
  4. /// a definition might be, it is possible to go from `a` to `b`,
  5. /// and from `b` to `a`.
  6. /// Going a roundway trip should leave you the same value.
  7. /// Unfortunately it is virtually impossible to test this.
  8. /// This is called ISO.
  9. pub enum Void { }
  10.  
  11. impl PartialEq for Void {
  12. fn eq(&self, _: &Void) -> bool {
  13. true
  14. }
  15. }
  16.  
  17. pub fn absurd(_: Void) -> ! {
  18. panic!("You must be kidding! Where did you find that void instance?");
  19. }
  20.  
  21. pub type ISO<A: 'static, B: 'static> = (Box<Fn(A) -> B>, Box<Fn(B) -> A>);
  22.  
  23. pub fn iso<A: 'static, B: 'static, F1, F2>(a: F1, b: F2) -> ISO<A, B>
  24. where F1: 'static + Fn(A) -> B,
  25. F2: 'static + Fn(B) -> A,
  26. {
  27. (Box::new(a), Box::new(b))
  28. }
  29.  
  30. /// given ISO a b, we can go from a to b
  31. pub fn sub_st_l<A, B>(iso: ISO<A, B>) -> Box<Fn(A) -> B> { iso.0 }
  32.  
  33. /// and vice versa
  34. pub fn sub_st_r<A, B>(iso: ISO<A, B>) -> Box<Fn(B) -> A> { iso.1 }
  35.  
  36. /// There can be more than one ISO a b
  37. pub fn iso_bool() -> ISO<bool, bool> {
  38. (Box::new(|x| x), Box::new(|x| x))
  39. }
  40.  
  41. pub fn iso_bool_not() -> ISO<bool, bool> {
  42. (Box::new(|x| !x), Box::new(|x| !x))
  43. }
  44.  
  45. /// isomorphism is reflexive
  46. pub fn refl<A: 'static>() -> ISO<A, A> {
  47. (Box::new(|x| x), Box::new(|x| x))
  48. }
  49.  
  50. /// isomorphism is symmetric
  51. pub fn symm<A: 'static, B: 'static>(i: ISO<A, B>) -> ISO<B, A> {
  52. (i.1, i.0)
  53. }
  54.  
  55. /// isomorphism is transitive
  56. pub fn trans<A: 'static, B: 'static, C: 'static>
  57. (ab: ISO<A, B>, bc: ISO<B, C>) -> ISO<A, C> {
  58. let (ab, ba) = ab;
  59. let (bc, cb) = bc;
  60. (Box::new(move |a| bc(ab(a))),
  61. Box::new(move |c| ba(cb(c))))
  62. }
  63.  
  64. /// we can combine isomorphism
  65. pub fn iso_tuple<A: 'static, B: 'static, C: 'static, D: 'static>
  66. (ab: ISO<A, B>, cd: ISO<C, D>) -> ISO<(A, C), (B, D)> {
  67. let (ab, ba) = ab;
  68. let (cd, dc) = cd;
  69. (Box::new(move |(a,c)| (ab(a), cd(c))),
  70. Box::new(move |(b,d)| (ba(b), dc(d))))
  71. }
  72.  
  73. pub fn iso_vec<A: 'static, B: 'static>(i: ISO<A, B>) -> ISO<Vec<A>, Vec<B>> {
  74. let (ab, ba) = i;
  75. (Box::new(move |v| v.into_iter().map(&*ab).collect()),
  76. Box::new(move |v| v.into_iter().map(&*ba).collect()))
  77. }
  78.  
  79. pub fn iso_option<A: 'static, B: 'static>
  80. (i: ISO<A, B>) -> ISO<Option<A>, Option<B>> {
  81. let (ab, ba) = i;
  82. (Box::new(move |a: Option<A>| a.map(&*ab)),
  83. Box::new(move |b: Option<B>| b.map(&*ba)))
  84. }
  85.  
  86. pub fn iso_result<A: 'static, B: 'static, C: 'static, D: 'static>
  87. (ab: ISO<A, B>, cd: ISO<C, D>) -> ISO<Result<A, C>, Result<B, D>> {
  88. let (ab, ba) = ab;
  89. let (cd, dc) = cd;
  90.  
  91. (Box::new(move |ac: Result<A, C>| ac.map(&*ab).map_err(&*cd)),
  92. Box::new(move |bd: Result<B, D>| bd.map(&*ba).map_err(&*dc)))
  93. }
  94.  
  95. /// Going another way is hard (and is generally impossible)
  96. /// Remember, for all valid ISO, converting and converting back
  97. /// is the same as the original value.
  98. /// You need this to prove some case are impossible.
  99. pub fn iso_un_option<A: 'static, B: 'static>
  100. (i: ISO<Option<A>, Option<B>>) -> ISO<A, B> {
  101. let (ab, ba) = i;
  102. (Box::new(move |a: A| ab(Some(a)).unwrap_or(ab(None).unwrap())),
  103. Box::new(move |b: B| ba(Some(b)).unwrap_or(ba(None).unwrap())))
  104. }
  105.  
  106. /// inf + 0 = inf + 1
  107. pub fn iso_eu() -> ISO<Result<Vec<()>, ()>, Result<Vec<()>, Void>> {
  108. let l2r = |a: Result<Vec<()>, ()>| {
  109. Ok( match a {
  110. Ok(v) => {
  111. let mut v = v.to_vec();
  112. v.push(());
  113. v
  114. }
  115. Err(_) => vec![]
  116. })
  117. };
  118.  
  119. let r2l = |b: Result<Vec<()>, Void>| {
  120. let mut v = b.unwrap_or(vec![]);
  121. if v.is_empty() {
  122. Err(())
  123. } else {
  124. v.pop();
  125. Ok(v)
  126. }
  127. };
  128.  
  129. (Box::new(l2r), Box::new(r2l))
  130. }
  131.  
  132. pub type IsoFL<A, B, C, D> = Box<FnOnce(Box<Fn(A) -> C>) -> Box<FnOnce(B) -> D>>;
  133. pub type IsoFR<A, B, C, D> = Box<FnOnce(Box<Fn(B) -> D>) -> Box<FnOnce(A) -> C>>;
  134. pub type IsoF<A, B, C, D> = (IsoFL<A, B, C, D>, IsoFR<A, B, C, D>);
  135.  
  136. /// translator note:
  137. /// FnBox is not yet supported, we can only return an uncallable
  138. /// Box<FnOnce> (RetFunc). You should return the function with
  139. /// correct type, which will be checked by the tests.
  140. /// The type annotation is shown above. You need you return something like
  141. /// (Box::new(...), Box::new(...))
  142. pub fn iso_func<A: 'static, B: 'static, C: 'static, D: 'static>
  143. (ab: ISO<A, B>, cd: ISO<C, D>) -> IsoF<A, B, C, D> {
  144. let (ab, ba) = ab;
  145. let (cd, dc) = cd;
  146. let f1: FnOnce(Box<Fn(A) -> C>) -> Box<FnOnce(B) -> D> = move |ac| {
  147. Box::new(|b: B| cd(ac(ba(b))))
  148. };
  149. let f2 = |bd: Box<Fn(B) -> D>| {
  150. Box::new(|a: A| dc(bd(ab(a))))
  151. };
  152.  
  153. //let f1: FnOnce(Box<Fn(A) -> C>) -> Box<FnOnce(B) -> D> = unimplemented!();
  154. //let f2: FnOnce(Box<Fn(B) -> D>) -> Box<FnOnce(A) -> C> = unimplemented!();
  155. (Box::new(f1), Box::new(f2))
  156. //unimplemented!()
  157. }
  158.  
  159. /// And we have isomorphism on isomorphism!
  160. pub fn iso_symm<A: 'static, B: 'static>() -> ISO<ISO<A, B>, ISO<B, A>> {
  161. (Box::new(symm), Box::new(symm))
  162. }
  163.  
  164.  
  165. /*************************************************************************************************/
  166. fn main() {
  167. for n in 1..10 {
  168. println!("going({})", n);
  169. }
  170. assert!(sub_st_l(iso_bool())(true));
  171. assert!(!sub_st_l(iso_bool())(false));
  172. assert!(sub_st_l(iso_bool_not())(false));
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement