File: value/core/morph/abstract.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: Value#8
  module: Core#10
  module: Morph#12
  class: Abstract#14
inherits from
  Object ( Umu::Value::Core )
has properties
class method: meth_make_empty (1/2) / 3 #28
class method: meth_make_cons / 5 #39
class method: meth_unfold / 5 #96
method: abstract_class #129
method: meth_cons / 4 #139
method: meth_make_empty (2/E) / 3 #151
method: meth_is_empty / 3 #161
method: meth_is_exists / 3 #175
method: meth_dest! / 3 #189
method: meth_dest / 3 #210
method: meth_head / 3 #220
method: meth_tail / 3 #239
method: meth_to_list / 3 #258
method: meth_susp / 3 #317
method: meth_susp_ / 3 #337
method: foldr / 5 #379
method: meth_foldr / 5 #401
method: foldl / 5 #416
method: meth_foldl / 5 #442
method: meth_reverse / 3 #462
method: meth_at / 4 #479
method: meth_at! / 4 #513
method: meth_count / 3 #552
method: meth_sum / 3 #569
method: meth_avg / 3 #610
method: meth_max / 3 #660
method: meth_min / 3 #702
method: meth_is_all / 4 #744
method: meth_is_any / 4 #768
method: meth_is_include / 4 #792
method: meth_for_each / 4 #816
method: meth_map / 4 #835
method: meth_select / 4 #857
method: meth_reject / 4 #883
method: meth_append / 4 #909
method: meth_concat / 3 #928
method: meth_concat_map / 4 #945
method: meth_join / 4 #972
method: meth_zip / 4 #1007
method: meth_unzip / 3 #1047
method: meth_uniq / 3 #1075
method: meth_partition / 4 #1123
method: meth_sort / 4 #1167

Class Hierarchy

Code

   1  # coding: utf-8
   2  # frozen_string_literal: true
   3 
   4 
   5 
   6  module Umu
   7 
   8  module Value
   9 
  10  module Core
  11 
  12  module Morph
  13 
  14  class Abstract < Object
  15  =begin
  16      The subclasses of this class must be implemented the following methods:
  17      * .meth_make_empty(loc, env, event) -> Morph::Abstract
  18      * #meth_cons(loc, env, event, value : VC::Top) -> Morph::Abstract
  19      * #meth_dest(loc, env, event) -> VCU::Option::Abstract
  20  =end
  21 
  22 
  23      define_class_method(
  24          :meth_make_empty,
  25          :empty, [],
  26          [], self
  27      )
  28      def self.meth_make_empty(_loc, _env, _event)
  29          # List is default morph
  30          VC.make_nil
  31      end
  32 
  33 
  34      define_class_method(
  35          :meth_make_cons,
  36          :cons, [:'head:tail:'],
  37          [VC::Top, self], self
  38      )
  39      def self.meth_make_cons(loc, env, event, x, xs)
  40          ASSERT.kind_of x,  VC::Top
  41          ASSERT.kind_of xs, VCM::Abstract
  42 
  43          xs.meth_cons loc, env, event, x
  44      end
  45 
  46 
  47  =begin
  48      HOW TO USE: unfoldr
  49 
  50      * Same to: [1 .. 5].to-list
  51 
  52          > &List.unfold 1 { x ->
  53          *     if x <= 5 then Some ([x], x + 1) else NONE
  54          * }
  55          val it : Cons = [1, 2, 3, 4, 5]
  56 
  57      * Same to: [1, 2, 3].map to-s
  58 
  59          > &List.unfold [1, 2, 3] { xs ->
  60          *     case xs of {
  61          *       [x|xs'] -> Some ([x.to-s], xs')
  62          *       else    -> NONE
  63          *     }
  64          * }
  65          val it : Cons = ["1", "2", "3"]
  66 
  67      * Same to: [1, 2, 3].select odd?
  68 
  69          > &List.unfold [1, 2, 3] { xs ->
  70          *     case xs of {
  71          *       [x|xs'] -> Some (if odd? x then [x] else [], xs')
  72          *       else    -> NONE
  73          *     }
  74          * }
  75          val it : Cons = [1, 3]
  76 
  77      * Same to: STDIN.each-line.to-list
  78 
  79          > &List.unfold STDIN { io ->
  80          *     case io.gets of {
  81          *       &Some s -> Some ([s], io)
  82          *       else    -> NONE
  83          *     }
  84          * }
  85          a
  86          b
  87          c
  88          [Ctrl]+[D]
  89          val it : Cons = ["a", "b", "c"]
  90  =end
  91      define_class_method(
  92          :meth_unfold,
  93          :unfold, [],
  94          [VC::Top, VC::Fun], self
  95      )
  96      def self.meth_unfold(loc, env, event, x, func)
  97          ASSERT.kind_of x,    VC::Top
  98          ASSERT.kind_of func, VC::Fun
  99 
 100          new_env = env.enter event
 101 
 102          _, result = loop.inject(
 103               [x,  self.meth_make_empty(loc, new_env, event)]
 104          ) { |(x1, yss                                      ), _|
 105              value = func.apply x1, [], loc, new_env
 106              ASSERT.kind_of value, VC::Top
 107 
 108              VC.validate_option value, 'unfoldl', loc, new_env
 109 
 110              case value
 111              when VCU::Option::None
 112                  break [x1, yss]
 113              when VCU::Option::Some
 114                  tuple      = value.contents
 115                  ys, next_x = VC.validate_pair tuple, "unfoldl", loc, env
 116 
 117                  VC.validate_morph ys, 'unfoldl', loc, new_env
 118 
 119                  [next_x, yss.meth_append(loc, new_env, event, ys)]
 120              else
 121                  ASSERT.abort "No case"
 122              end
 123          }
 124 
 125          ASSERT.kind_of result, VC::Top
 126      end
 127 
 128 
 129      def abstract_class
 130          VCM::Abstract
 131      end
 132 
 133 
 134      define_instance_method(
 135          :meth_cons,
 136          :cons, [],
 137          [VC::Top], self
 138      )
 139      def meth_cons(_loc, _env, _event, value)
 140          ASSERT.kind_of value, VC::Top
 141 
 142          raise X::InternalSubclassResponsibility
 143      end
 144 
 145 
 146      define_instance_method(
 147          :meth_make_empty,
 148          :empty, [],
 149          [], self
 150      )
 151      def meth_make_empty(loc, env, event)
 152          self.class.meth_make_empty loc, env, event
 153      end
 154 
 155 
 156      define_instance_method(
 157          :meth_is_empty,
 158          :empty?, [],
 159          [], VCA::Bool
 160      )
 161      def meth_is_empty(_loc, _env, _event)
 162          val_opt = self.meth_dest loc, env, event
 163 
 164          VC.validate_option val_opt, 'empty?', loc, env
 165 
 166          VC.make_bool val_opt.none?
 167      end
 168 
 169 
 170      define_instance_method(
 171          :meth_is_exists,
 172          :exists?, [],
 173          [], VCA::Bool
 174      )
 175      def meth_is_exists(loc, env, event)
 176          val_opt = self.meth_dest loc, env, event
 177 
 178          VC.validate_option val_opt, 'exists?', loc, env
 179 
 180          VC.make_bool val_opt.some?
 181      end
 182 
 183 
 184      define_instance_method(
 185          :meth_dest!,
 186          :dest!, [],
 187          [], VCP::Tuple
 188      )
 189      def meth_dest!(loc, env, event)
 190          val_opt = self.meth_dest loc, env, event
 191 
 192          VC.validate_option val_opt, 'dest!', loc, env
 193 
 194          unless val_opt.some?
 195              raise X::EmptyError.new loc, env, "dest!: Empty morph"
 196          end
 197 
 198          pair = val_opt.contents
 199          VC.validate_pair pair, "dest!", loc, env
 200 
 201          ASSERT.kind_of pair,  VCP::Tuple
 202      end
 203 
 204 
 205      define_instance_method(
 206          :meth_dest,
 207          :dest, [],
 208          [], VCU::Option::Abstract
 209      )
 210      def meth_dest(_loc, _env, _event)
 211          raise X::InternalSubclassResponsibility
 212      end
 213 
 214 
 215      define_instance_method(
 216          :meth_head,
 217          :head, [],
 218          [], VC::Top
 219      )
 220      def meth_head(loc, env, event)
 221          val_opt = self.meth_dest loc, env, event
 222 
 223          VC.validate_option val_opt, 'head', loc, env
 224          unless val_opt.some?
 225              raise X::EmptyError.new loc, env, "head: Empty morph"
 226          end
 227 
 228          result, _ = VC.validate_pair val_opt.contents, "head", loc, env
 229 
 230          result
 231      end
 232 
 233 
 234      define_instance_method(
 235          :meth_tail,
 236          :tail, [],
 237          [], self
 238      )
 239      def meth_tail(loc, env, event)
 240          val_opt = self.meth_dest loc, env, event
 241 
 242          VC.validate_option val_opt, 'tail', loc, env
 243          unless val_opt.some?
 244              raise X::EmptyError.new loc, env, "tail: Empty morph"
 245          end
 246 
 247          _, result = VC.validate_pair val_opt.contents, "tail", loc, env
 248 
 249          result
 250      end
 251 
 252 
 253      define_instance_method(
 254          :meth_to_list,
 255          :'to-list', [],
 256          [], VCM::List::Abstract
 257      )
 258      def meth_to_list(loc, env, event)
 259          zs = loop.inject(
 260               [VC.make_nil, self]
 261          ) { |(ys,          xs), _|
 262              val_of_opt = xs.meth_dest(loc, env, event)
 263              case val_of_opt
 264              when VCU::Option::None
 265                  break ys
 266              when VCU::Option::Some
 267                  pair = val_of_opt.contents
 268                  ASSERT.kind_of pair, VCP::Tuple
 269                  x, xs1 = pair.values
 270 
 271                  [ys.meth_cons(loc, env, event, x), xs1]
 272              else
 273                  ASSERT.abort "No case: ", val_of_opt.inspect
 274              end
 275          }
 276 
 277          result = zs.meth_reverse(loc, env, event)
 278 
 279          ASSERT.kind_of result, VCM::List::Abstract
 280      end
 281 
 282 
 283  =begin
 284  HOW TO USE Morph#susp
 285 
 286      * If not exists 'susp', then ...
 287 
 288          > STDIN.each-line.map { s -> "- " ^ s }.for-each print
 289          aaa [Enter]
 290          bbb [Enter]
 291          ccc [Enter]
 292          [Ctrl]+[d]
 293          - aaa
 294          - bbb
 295          - ccc
 296          val it : Unit = ()
 297          >
 298 
 299      * Use 'susp'
 300 
 301          > STDIN.each-line.susp.map { s -> "- " ^ s }.for-each print
 302          aaa [Enter]
 303          - aaa
 304          bbb [Enter]
 305          - bbb
 306          ccc [Enter]
 307          - ccc
 308          [Ctrl]+[d]
 309          val it : Unit = ()
 310          >
 311  =end
 312      define_instance_method(
 313          :meth_susp,
 314          :susp, [],
 315          [], VCM::Stream::Entry::Abstract
 316      )
 317      def meth_susp(loc, env, event)
 318          sym_this = :this
 319 
 320          new_env = env.va_extend_value sym_this, self
 321 
 322          expr = ASCE.make_send(
 323                  loc,
 324                  ASCE.make_identifier(loc, sym_this),
 325                  ASCE.make_message(loc, :'%susp')
 326              )
 327 
 328          VC.make_suspended_stream(expr, new_env.va_context)
 329      end
 330 
 331 
 332      define_instance_method(
 333          :meth_susp_,
 334          :'%susp', [],
 335          [], VCM::Stream::Entry::Abstract
 336      )
 337      def meth_susp_(loc, env, event)
 338          val_opt = self.meth_dest loc, env, event
 339 
 340          VC.validate_option val_opt, 'susp', loc, env
 341 
 342          result = (
 343              if val_opt.none?
 344                  VC.make_cell_stream_nil env.va_context
 345              else
 346                  sym_x   = :'%x'
 347                  sym_xs  = :'%xs'
 348 
 349                  x, xs = VC.validate_pair val_opt.contents, 'susp', loc, env
 350 
 351                  VC.validate_morph xs, 'susp', loc, env
 352                  new_env = env.va_extend_values(
 353                                      sym_x   => x,
 354                                      sym_xs  => xs
 355                                  )
 356 
 357                  VC.make_cell_stream_cons(
 358                      ASCE.make_identifier(loc, sym_x),
 359 
 360                      VC.make_expr_stream_entry(
 361                           ASCE.make_send(
 362                              loc,
 363                              ASCE.make_identifier(loc, sym_xs),
 364                              ASCE.make_message(loc, :susp)
 365                          ),
 366 
 367                          new_env.va_context
 368                      ),
 369 
 370                      new_env.va_context
 371                  )
 372              end
 373          )
 374 
 375          ASSERT.kind_of result, VCM::Stream::Entry::Abstract
 376      end
 377 
 378 
 379      def foldr(loc, env, event, init, &block)
 380          ASSERT.kind_of init,  VC::Top
 381          ASSERT.kind_of block, ::Proc
 382 
 383          result = self.foldl(
 384               loc,     env,     event, self.meth_make_empty(loc, env, event)
 385          ) { |new_loc, new_env, x,     xs|
 386 
 387               xs.meth_cons new_loc, new_env, event, x
 388          }.foldl(
 389              loc, env, event, init, &block
 390          )
 391 
 392          ASSERT.kind_of result, VC::Top
 393      end
 394 
 395 
 396      define_instance_method(
 397          :meth_foldr,
 398          :foldr, [],
 399          [VC::Top, VC::Fun], VC::Top
 400      )
 401      def meth_foldr(loc, env, event, init, func)
 402          ASSERT.kind_of init,    VC::Top
 403          ASSERT.kind_of func,    VC::Fun
 404 
 405          result = self.foldr(
 406               loc,     env,     event, init
 407          ) { |new_loc, new_env, x,     y|
 408 
 409              func.apply x, [y], new_loc, new_env
 410          }
 411 
 412          ASSERT.kind_of result, VC::Top
 413      end
 414 
 415 
 416      def foldl(loc, env, event, init, &block)
 417          ASSERT.kind_of init,  VC::Top
 418          ASSERT.kind_of block, ::Proc
 419 
 420          mut_y  = init.dup
 421          mut_xs = self.dup
 422          loop do
 423              val_opt = mut_xs.meth_dest loc, env, event
 424              break if val_opt.none?
 425 
 426              pair      = val_opt.contents
 427              x, mut_xs = VC.validate_pair pair, "foldl", loc, env
 428              VC.validate_morph mut_xs, 'foldl', loc, env
 429 
 430              mut_y = yield loc, env, x, mut_y
 431          end
 432 
 433          ASSERT.kind_of mut_y, VC::Top
 434      end
 435 
 436 
 437      define_instance_method(
 438          :meth_foldl,
 439          :foldl, [],
 440          [VC::Top, VC::Fun], VC::Top
 441      )
 442      def meth_foldl(loc, env, event, init, func)
 443          ASSERT.kind_of init,    VC::Top
 444          ASSERT.kind_of func,    VC::Fun
 445 
 446          result = self.foldl(
 447               loc,     env,     event, init
 448          ) { |new_loc, new_env, x,     y|
 449 
 450              func.apply x, [y], new_loc, new_env
 451          }
 452 
 453          ASSERT.kind_of result, VC::Top
 454      end
 455 
 456 
 457      define_instance_method(
 458          :meth_reverse,
 459          :reverse, [],
 460          [], self
 461      )
 462      def meth_reverse(loc, env, event)
 463          result = self.foldl(
 464               loc,     env,     event, self.meth_make_empty(loc, env, event)
 465          ) { |new_loc, new_env, x,     xs|
 466 
 467               xs.meth_cons new_loc, new_env, event, x
 468          }
 469 
 470          ASSERT.kind_of result, VC::Top
 471      end
 472 
 473 
 474      define_instance_method(
 475          :meth_at,
 476          :at, [],
 477          [VCAN::Int], VCU::Option::Abstract
 478      )
 479      def meth_at(loc, env, event, target_index)
 480          ASSERT.opt_kind_of target_index, VCAN::Int
 481 
 482          target_index_val = target_index.val
 483          unless target_index_val >= 0
 484              raise X::ArgumentError.new(
 485                  loc,
 486                  env,
 487                  "at: Expected zero or positive integer, but: %d",
 488                  target_index_val
 489              )
 490          end
 491 
 492          result = self.foldl(
 493               loc,     env,       event, VC.make_opaque([0, VC.make_none])
 494          ) { |new_loc, new_event, x,     opaque|
 495 
 496              index_val, opt = opaque.obj
 497              if index_val == target_index_val
 498                  break VC.make_opaque [index_val, VC.make_some(x)]
 499              end
 500 
 501              VC.make_opaque [index_val + 1, opt]
 502          }
 503 
 504          ASSERT.kind_of result.obj[1], VCU::Option::Abstract
 505      end
 506 
 507 
 508      define_instance_method(
 509          :meth_at!,
 510          :'at!', [:apply],
 511          [VCAN::Int], VC::Top
 512      )
 513      def meth_at!(loc, env, event, target_index)
 514          ASSERT.opt_kind_of target_index, VCAN::Int
 515 
 516          target_index_val = target_index.val
 517          unless target_index_val >= 0
 518              raise X::ArgumentError.new(
 519                  loc,
 520                  env,
 521                  "at!: Expected zero or positive integer, but: %d",
 522                  target_index_val
 523              )
 524          end
 525 
 526          self.foldl(
 527                loc,     env,       event, VC.make_opaque(0)
 528          ) do |new_loc, new_event, x,     opaque|
 529 
 530              index_val = opaque.obj
 531              if index_val == target_index_val
 532                  return x
 533              end
 534 
 535              VC.make_opaque(index_val + 1)
 536          end
 537 
 538          raise X::IndexError.new(
 539              loc,
 540              env,
 541              "at!: Out of range index: %d",
 542              target_index_val
 543          )
 544      end
 545 
 546 
 547      define_instance_method(
 548          :meth_count,
 549          :count, [],
 550          [], VCAN::Int
 551      )
 552      def meth_count(loc, env, event)
 553          result = self.foldl(
 554               loc,     env,     event, VC.make_integer_zero
 555          ) { |new_loc, new_env, _,     n|
 556 
 557               n.meth_succ new_loc, new_env, event
 558          }
 559 
 560          ASSERT.kind_of result, VCAN::Int
 561      end
 562 
 563 
 564      define_instance_method(
 565          :meth_sum,
 566          :sum, [],
 567          [], VCAN::Abstract
 568      )
 569      def meth_sum(loc, env, event)
 570          val_opt = self.meth_dest loc, env, event
 571 
 572          VC.validate_option val_opt, 'sum', loc, env
 573          unless val_opt.some?
 574              raise X::EmptyError.new loc, env, "sum: Empty morph"
 575          end
 576 
 577          head, _ = VC.validate_pair val_opt.contents, 'sum', loc, env
 578          VC.validate_number head, 'sum', loc, env
 579 
 580          zero = head.meth_zero loc, env, event
 581          zero_class_signat = env.ty_class_signat_of zero
 582 
 583          result = self.foldl(
 584               loc,     env,     event, zero
 585          ) { |new_loc, new_env, x,     sum|
 586 
 587              unless env.ty_kind_of?(x, zero_class_signat)
 588                  raise X::TypeError.new(
 589                      new_loc,
 590                      new_env,
 591                      "sum: Expected a %s, but %s : %s",
 592                      zero_class_signat.symbol.to_s,
 593                      x.to_s,
 594                      x.type_sym.to_s
 595                  )
 596              end
 597 
 598              sum.meth_add new_loc, new_env, event, x
 599          }
 600 
 601          ASSERT.kind_of result, VCAN::Abstract
 602      end
 603 
 604 
 605      define_instance_method(
 606          :meth_avg,
 607          :avg, [],
 608          [], VCAN::Abstract
 609      )
 610      def meth_avg(loc, env, event)
 611          val_opt = self.meth_dest loc, env, event
 612 
 613          VC.validate_option val_opt, 'avg', loc, env
 614          unless val_opt.some?
 615              raise X::EmptyError.new loc, env, "avg: Empty morph"
 616          end
 617 
 618          head, _ = VC.validate_pair val_opt.contents, 'avg', loc, env
 619          VC.validate_number head, 'avg', loc, env
 620 
 621          zero = head.meth_zero loc, env, event
 622          zero_class_signat = env.ty_class_signat_of zero
 623 
 624          result_opaque = self.foldl(
 625               loc,     env,     event, VC.make_opaque([zero, zero])
 626          ) { |new_loc, new_env, x,     opaque|
 627 
 628              unless env.ty_kind_of?(x, zero_class_signat)
 629                  raise X::TypeError.new(
 630                      new_loc,
 631                      new_env,
 632                      "avg: Expected a %s, but %s : %s",
 633                      zero_class_signat.symbol.to_s,
 634                      x.to_s,
 635                      x.type_sym.to_s
 636                  )
 637              end
 638 
 639              va_sum, va_count = opaque.obj
 640 
 641              VC.make_opaque(
 642                  [
 643                      va_sum.meth_add(loc, env, event, x),
 644                      va_count.meth_succ(loc, env, event)
 645                  ]
 646              )
 647          }
 648 
 649          res_sum, res_count = result_opaque.obj
 650 
 651          res_sum.meth_divide(loc, env, event, res_count)
 652      end
 653 
 654 
 655      define_instance_method(
 656          :meth_max,
 657          :max, [],
 658          [], VCAN::Abstract
 659      )
 660      def meth_max(loc, env, event)
 661          val_opt = self.meth_dest loc, env, event
 662 
 663          VC.validate_option val_opt, 'max', loc, env
 664          unless val_opt.some?
 665              raise X::EmptyError.new loc, env, "max: Empty morph"
 666          end
 667 
 668          head, _ = VC.validate_pair val_opt.contents, 'max', loc, env
 669          VC.validate_number head, 'max', loc, env
 670 
 671          head_class_signat = env.ty_class_signat_of head
 672 
 673          self.meth_tail(loc, env, event).foldl(
 674               loc,     env,       event, head
 675          ) { |new_loc, new_event, x,     y|
 676 
 677              unless env.ty_kind_of?(y, head_class_signat)
 678                  raise X::TypeError.new(
 679                      new_loc,
 680                      new_env,
 681                      "max: Expected a %s, but %s : %s",
 682                      head_class_signat.symbol.to_s,
 683                      y.to_s,
 684                      y.type_sym.to_s
 685                  )
 686              end
 687 
 688              if y.meth_is_less_than(loc, env, event, x).true?
 689                  x
 690              else
 691                  y
 692              end
 693          }
 694      end
 695 
 696 
 697      define_instance_method(
 698          :meth_min,
 699          :min, [],
 700          [], VCAN::Abstract
 701      )
 702      def meth_min(loc, env, event)
 703          val_opt = self.meth_dest loc, env, event
 704 
 705          VC.validate_option val_opt, 'max', loc, env
 706          unless val_opt.some?
 707              raise X::EmptyError.new loc, env, "max: Empty morph"
 708          end
 709 
 710          head, _ = VC.validate_pair val_opt.contents, 'max', loc, env
 711          VC.validate_number head, 'min', loc, env
 712 
 713          head_class_signat = env.ty_class_signat_of head
 714 
 715          self.meth_tail(loc, env, event).foldl(
 716               loc,     env,       event, head
 717          ) { |new_loc, new_event, x,     y|
 718 
 719              unless env.ty_kind_of?(y, head_class_signat)
 720                  raise X::TypeError.new(
 721                      new_loc,
 722                      new_env,
 723                      "min: Expected a %s, but %s : %s",
 724                      head_class_signat.symbol.to_s,
 725                      y.to_s,
 726                      y.type_sym.to_s
 727                  )
 728              end
 729 
 730              if x.meth_is_less_than(loc, env, event, y).true?
 731                  x
 732              else
 733                  y
 734              end
 735          }
 736      end
 737 
 738 
 739      define_instance_method(
 740          :meth_is_all,
 741          :all?, [],
 742          [VC::Fun], VCA::Bool
 743      )
 744      def meth_is_all(loc, env, event, func)
 745          ASSERT.kind_of func, VC::Fun
 746 
 747          result = self.foldl(
 748               loc,     env,     event, VC.make_true
 749          ) { |new_loc, new_env, x,     bool|
 750 
 751              value = func.apply x, [], new_loc, new_env
 752              VC.validate_bool value, 'all?', loc, env
 753 
 754              break VC.make_false if value.false?
 755 
 756              bool
 757          }
 758 
 759          ASSERT.kind_of result, VCA::Bool
 760      end
 761 
 762 
 763      define_instance_method(
 764          :meth_is_any,
 765          :any?, [],
 766          [VC::Fun], VCA::Bool
 767      )
 768      def meth_is_any(loc, env, event, func)
 769          ASSERT.kind_of func, VC::Fun
 770 
 771          result = self.foldl(
 772               loc,     env,     event, VC.make_false
 773          ) { |new_loc, new_env, x,     bool|
 774 
 775              value = func.apply x, [], new_loc, new_env
 776              VC.validate_bool value, 'any?', loc, env
 777 
 778              break VC.make_true if value.true?
 779 
 780              bool
 781          }
 782 
 783          ASSERT.kind_of result, VCA::Bool
 784      end
 785 
 786 
 787      define_instance_method(
 788          :meth_is_include,
 789          :include?, [],
 790          [VC::Top], VCA::Bool
 791      )
 792      def meth_is_include(loc, env, event, member)
 793          ASSERT.kind_of member, VC::Top
 794 
 795          result = self.foldl(
 796               loc,     env,     event, VC.make_false
 797          ) { |new_loc, new_env, x,     bool|
 798 
 799              value = x.meth_is_equal loc, new_env, event, member
 800              VC.validate_bool value, 'include?', loc, env
 801 
 802              break VC.make_true if value.true?
 803 
 804              bool
 805          }
 806 
 807          ASSERT.kind_of result, VCA::Bool
 808      end
 809 
 810 
 811      define_instance_method(
 812          :meth_for_each,
 813          :'for-each', [],
 814          [VC::Fun], VC::Unit
 815      )
 816      def meth_for_each(loc, env, event, func)
 817          ASSERT.kind_of func, VC::Fun
 818 
 819          self.foldl(
 820                loc,     env,     event, VC.make_unit
 821          ) do |new_loc, new_env, x,     _|
 822 
 823               func.apply x, [], loc, new_env
 824          end
 825 
 826          VC.make_unit
 827      end
 828 
 829 
 830      define_instance_method(
 831          :meth_map,
 832          :map, [],
 833          [VC::Fun], self
 834      )
 835      def meth_map(loc, env, event, func)
 836          ASSERT.kind_of func, VC::Fun
 837 
 838          result = self.foldr(
 839               loc,     env,     event, self.meth_make_empty(loc, env, event)
 840          ) { |new_loc, new_env, x,     ys|
 841 
 842              ys.meth_cons(
 843                  new_loc, new_env, event, 
 844                  func.apply(x, [], new_loc, new_env)
 845              )
 846          }
 847 
 848          ASSERT.kind_of result, self.abstract_class
 849      end
 850 
 851 
 852      define_instance_method(
 853          :meth_select,
 854          :select, [],
 855          [VC::Fun], self
 856      )
 857      def meth_select(loc, env, event, func)
 858          ASSERT.kind_of func, VC::Fun
 859 
 860          result = self.foldr(
 861               loc,     env,     event, self.meth_make_empty(loc, env, event)
 862          ) { |new_loc, new_env, x,     ys|
 863 
 864              value = func.apply x, [], new_loc, new_env
 865              VC.validate_bool value, 'select', new_loc, new_env
 866 
 867              if value.true?
 868                  ys.meth_cons new_loc, new_env, event, x
 869              else
 870                  ys
 871              end
 872          }
 873 
 874          ASSERT.kind_of result, self.abstract_class
 875      end
 876 
 877 
 878      define_instance_method(
 879          :meth_reject,
 880          :reject, [],
 881          [VC::Fun], self
 882      )
 883      def meth_reject(loc, env, event, func)
 884          ASSERT.kind_of func, VC::Fun
 885 
 886          result = self.foldr(
 887               loc,     env,     event, self.meth_make_empty(loc, env, event)
 888          ) { |new_loc, new_env, x,     ys|
 889 
 890              value = func.apply x, [], new_loc, new_env
 891              VC.validate_bool value, 'reject', new_loc, new_env
 892 
 893              if value.false?
 894                  ys.meth_cons new_loc, new_env, event, x
 895              else
 896                  ys
 897              end
 898          }
 899 
 900          ASSERT.kind_of result, self.abstract_class
 901      end
 902 
 903 
 904      define_instance_method(
 905          :meth_append,
 906          :'++', [],
 907          [self], self
 908      )
 909      def meth_append(loc, env, event, ys)
 910          ASSERT.kind_of ys, Abstract
 911 
 912          result = self.foldr(
 913                           loc,     env,     event, ys
 914                      ) { |new_loc, new_env, x,     ys1|
 915 
 916                          ys1.meth_cons new_loc, new_env, event, x
 917                      }
 918 
 919          ASSERT.kind_of result, VCM::Abstract
 920      end
 921 
 922 
 923      define_instance_method(
 924          :meth_concat,
 925          :concat, [],
 926          [], self
 927      )
 928      def meth_concat(loc, env, event)
 929          result = self.foldl(
 930               loc,     env,     event, self.meth_make_empty(loc, env, event)
 931          ) { |new_loc, new_env, xs,    xss|
 932 
 933              xss.meth_append new_loc, new_env, event, xs
 934          }
 935 
 936          ASSERT.kind_of result, self.abstract_class
 937      end
 938 
 939 
 940      define_instance_method(
 941          :meth_concat_map,
 942          :'concat-map', [],
 943          [VC::Fun], self
 944      )
 945      def meth_concat_map(loc, env, event, func)
 946          ASSERT.kind_of func, VC::Fun
 947 
 948          result = self.foldl(
 949               loc,     env,     event, self.meth_make_empty(loc, env, event)
 950          ) { |new_loc, new_env, x,     yss|
 951 
 952              xs = func.apply x, [], new_loc, new_env
 953              VC.validate_morph xs, 'concat-map', new_loc, new_env
 954 
 955              yss.meth_append new_loc, new_env, event, xs
 956          }
 957 
 958          ASSERT.kind_of result, self.abstract_class
 959      end
 960 
 961 
 962      define_instance_method(
 963          :meth_join,
 964          :join, [],
 965          [], VCA::String
 966      )
 967      define_instance_method(
 968          :meth_join,
 969          :'join-by', [:'join:'],
 970          [VCA::String], VCA::String
 971      )
 972      def meth_join(loc, env, event, sep_value = nil)
 973          ASSERT.opt_kind_of sep_value, VCA::String
 974 
 975          result = self.foldl(
 976               loc,     env,     event, VC.make_opaque(["", true])
 977          ) { |new_loc, new_env, x,     opaque|
 978 
 979              VC.validate_string x, 'join', new_loc, new_env
 980 
 981              s, is_first = opaque.obj
 982 
 983              VC.make_opaque(
 984                  [
 985                      s + (
 986                          if sep_value && ! is_first
 987                              sep_value.val
 988                          else
 989                              ""
 990                          end
 991                      ) + x.val,
 992 
 993                      false
 994                  ]
 995              )
 996          }
 997 
 998          VC.make_string (result.obj)[0]
 999      end
1000 
1001 
1002      define_instance_method(
1003          :meth_zip,
1004          :zip, [],
1005          [self], self
1006      )
1007      def meth_zip(loc, env, event, ys)
1008          ASSERT.kind_of ys, Abstract
1009 
1010          _, _, zs = loop.inject(
1011               [self, ys,  self.meth_make_empty(loc, env, event)]
1012          ) { |(xs1,  ys1, zs1        ), _|
1013 
1014              xs_opt = xs1.meth_dest loc, env, event
1015              ys_opt = ys1.meth_dest loc, env, event
1016 
1017              if xs_opt.none? || ys_opt.none?
1018                  break [xs1, ys1, zs1]
1019              else
1020                  xs_pair = xs_opt.contents
1021                  x, xs2 = VC.validate_pair xs_pair, "zip", loc, env
1022 
1023                  ys_pair = ys_opt.contents
1024                  y, ys2 = VC.validate_pair ys_pair, "zip", loc, env
1025 
1026                  [
1027                      xs2,
1028                      ys2,
1029                      zs1.meth_cons(loc, env, event,
1030                          VC.make_tuple(x, y)
1031                      )
1032                  ]
1033              end
1034          }
1035 
1036          result = zs.meth_reverse loc, env, event
1037 
1038          ASSERT.kind_of result, self.abstract_class
1039      end
1040 
1041 
1042      define_instance_method(
1043          :meth_unzip,
1044          :unzip, [],
1045          [], VCP::Tuple
1046      )
1047      def meth_unzip(loc, env, event)
1048          result = self.foldr(
1049               loc,     env,     event,
1050               VC.make_tuple(
1051                  self.meth_make_empty(loc, env, event),
1052                  self.meth_make_empty(loc, env, event)
1053               )
1054          ) { |new_loc, new_env, y_z,     ys_zs|
1055 
1056              y,  z  = VC.validate_pair y_z,   "unzip", new_loc, new_env
1057              ys, zs = VC.validate_pair ys_zs, "unzip", new_loc, new_env
1058              ys, zs = ys_zs.values
1059 
1060              VC.make_tuple(
1061                  ys.meth_cons(loc, env, event, y),
1062                  zs.meth_cons(loc, env, event, z)
1063              )
1064          }
1065 
1066          ASSERT.kind_of result, VCP::Tuple
1067      end
1068 
1069 
1070      define_instance_method(
1071          :meth_uniq,
1072          :uniq, [],
1073          [], self
1074      )
1075      def meth_uniq(loc, env, event)
1076          val_opt  = self.meth_dest loc, env, event
1077          VC.validate_option val_opt, 'uniq', loc, env
1078 
1079          if val_opt.none?
1080              self
1081          else
1082              x, xs = VC.validate_pair val_opt.contents, "uniq", loc, env
1083 
1084              xs_opt  = xs.meth_dest loc, env, event
1085              VC.validate_option xs_opt, 'uniq', loc, env
1086 
1087              if xs_opt.none?
1088                  self
1089              else
1090                  result_opaque = xs.foldl(
1091                       loc,     env,     event,
1092                       VC.make_opaque([x, VC.make_list([x])])
1093                  ) { |new_loc, new_env, x1,    opaque|
1094 
1095                      before, ys = opaque.obj
1096 
1097                      VC.make_opaque(
1098                          [
1099                              x1,
1100 
1101                              if x1.meth_is_equal(
1102                                  loc, env, event, before
1103                              ).true? 
1104                                  ys
1105                              else
1106                                  ys.meth_cons loc, env, event, x1
1107                              end
1108                          ]
1109                      )
1110                  }
1111 
1112                  (result_opaque.obj)[1].meth_reverse loc, env, event
1113              end
1114          end
1115      end
1116 
1117 
1118      define_instance_method(
1119          :meth_partition,
1120          :partition, [],
1121          [VC::Fun], VCP::Tuple
1122      )
1123      def meth_partition(loc, env, event, func)
1124          ASSERT.kind_of func, VC::Fun
1125 
1126          init_opaque = VC.make_opaque [
1127                                  self.meth_make_empty(loc, env, event),
1128                                  self.meth_make_empty(loc, env, event)
1129                              ]
1130 
1131          result_opaque = self.foldr(
1132               loc,     env,     event, init_opaque
1133          ) { |new_loc, new_env, x,     opaque|
1134 
1135              value = func.apply(x, [], loc, new_env)
1136              VC.validate_bool value, 'partition', new_loc, new_env
1137 
1138              ys, zs = opaque.obj
1139 
1140              if value.true?
1141                  VC.make_opaque([
1142                      ys.meth_cons(loc, env, event, x),
1143                      zs
1144                  ])
1145              else
1146                  VC.make_opaque([
1147                      ys,
1148                      zs.meth_cons(loc, env, event, x)
1149                  ])
1150              end
1151          }
1152 
1153          VC.make_tuple result_opaque.obj[0], result_opaque.obj[1]
1154      end
1155 
1156 
1157      define_instance_method(
1158          :meth_sort,
1159          :sort, [],
1160          [], self
1161      )
1162      define_instance_method(
1163          :meth_sort,
1164          :'sort-with', [],
1165          [VC::Fun], self
1166      )
1167      def meth_sort(loc, env, event, opt_func = nil)
1168          ASSERT.opt_kind_of opt_func, VC::Fun
1169 
1170          val_opt = self.meth_dest loc, env, event
1171 
1172          VC.validate_option val_opt, 'head', loc, env
1173          unless val_opt.none?
1174              return self
1175          end
1176 
1177          pivot, xs = VC.validate_pair val_opt.contents, "sort", loc, env
1178 
1179          init_opaque = VC.make_opaque [
1180                                  self.meth_make_empty(loc, env, event),
1181                                  self.meth_make_empty(loc, env, event)
1182                              ]
1183 
1184          result_opaque = xs.foldr(
1185               loc,     env,     event, init_opaque
1186          ) { |new_loc, new_env, x,     opaque|
1187 
1188              compare_result = if opt_func
1189                      func = opt_func
1190 
1191                      value = func.apply x, [pivot], new_loc, new_env
1192                      VC.validate_int value, 'sort', new_loc, new_env
1193 
1194                      value.val
1195                  else
1196                      if x.meth_is_less_than(
1197                          new_loc, new_env, event, pivot
1198                      ).true?
1199                          -1
1200                      else
1201                          1
1202                      end
1203                  end
1204 
1205              ys, zs = opaque.obj
1206 
1207              if compare_result < 0
1208                  VC.make_opaque([
1209                      ys.meth_cons(loc, env, event, x),
1210                      zs
1211                  ])
1212              else
1213                  VC.make_opaque([
1214                      ys,
1215                      zs.meth_cons(loc, env, event, x)
1216                  ])
1217              end
1218          }
1219          littles, bigs = result_opaque.obj
1220 
1221          littles1 = littles.meth_sort loc, env, event, opt_func
1222          bigs1    = bigs   .meth_sort loc, env, event, opt_func
1223 
1224          result = littles1.meth_append(loc, env, event,
1225                                  bigs1.meth_cons(loc, env, event, pivot)
1226                              )
1227 
1228          ASSERT.kind_of result, self.abstract_class
1229      end
1230  end
1231  Abstract.freeze
1232 
1233  end # Umu::Value::Core::Morph
1234 
1235  end # Umu::Value::Core
1236 
1237  end # Umu::Value
1238 
1239  end # Umu